haogh 11 ay önce
işleme
8cac98e001
100 değiştirilmiş dosya ile 16457 ekleme ve 0 silme
  1. 13 0
      .editorconfig
  2. 39 0
      .gitignore
  3. 27 0
      README.md
  4. 166 0
      angular.json
  5. 28 0
      e2e/protractor.conf.js
  6. 14 0
      e2e/src/app.e2e-spec.ts
  7. 11 0
      e2e/src/app.po.ts
  8. 13 0
      e2e/tsconfig.e2e.json
  9. 32 0
      modernizr-config.json
  10. 10640 0
      package-lock.json
  11. 96 0
      package.json
  12. 5 0
      proxy.conf.json
  13. 3 0
      src/app/app.component.html
  14. 0 0
      src/app/app.component.scss
  15. 60 0
      src/app/app.component.ts
  16. 89 0
      src/app/app.module.ts
  17. 1 0
      src/app/core/ajax/ajax.component.html
  18. 158 0
      src/app/core/ajax/ajax.component.ts
  19. 148 0
      src/app/core/ajax/ajax.service.ts
  20. 26 0
      src/app/core/core.module.ts
  21. 349 0
      src/app/core/frame/frame.service.ts
  22. 31 0
      src/app/core/menu/menu.service.ts
  23. 6 0
      src/app/core/module-import-guard.ts
  24. 13 0
      src/app/core/msg/form-msg/form-msg.component.html
  25. 45 0
      src/app/core/msg/form-msg/form-msg.component.ts
  26. 127 0
      src/app/core/msg/msg.service.ts
  27. 55 0
      src/app/core/pager/pager.component.html
  28. 382 0
      src/app/core/pager/pager.component.ts
  29. 3 0
      src/app/core/preloader/preloader.component.html
  30. 51 0
      src/app/core/preloader/preloader.js
  31. 71 0
      src/app/core/preloader/preloader.scss
  32. 66 0
      src/app/core/settings/settings.service.ts
  33. 68 0
      src/app/core/themes/themes.service.ts
  34. 4 0
      src/app/core/uploader/uploader.component.html
  35. 149 0
      src/app/core/uploader/uploader.component.ts
  36. 436 0
      src/app/core/wrapper/wrapper.js
  37. 2 0
      src/app/index.ts
  38. 1 0
      src/app/layout/footer/footer.component.html
  39. 0 0
      src/app/layout/footer/footer.component.scss
  40. 17 0
      src/app/layout/footer/footer.component.ts
  41. 126 0
      src/app/layout/header/header.component.h.html
  42. 131 0
      src/app/layout/header/header.component.html
  43. 0 0
      src/app/layout/header/header.component.scss
  44. 73 0
      src/app/layout/header/header.component.ts
  45. 15 0
      src/app/layout/layout.component.h.html
  46. 17 0
      src/app/layout/layout.component.html
  47. 0 0
      src/app/layout/layout.component.scss
  48. 15 0
      src/app/layout/layout.component.ts
  49. 44 0
      src/app/layout/layout.module.ts
  50. 350 0
      src/app/layout/offsidebar/offsidebar.component.html
  51. 0 0
      src/app/layout/offsidebar/offsidebar.component.scss
  52. 49 0
      src/app/layout/offsidebar/offsidebar.component.ts
  53. 116 0
      src/app/layout/sidebar/sidebar.component.html
  54. 0 0
      src/app/layout/sidebar/sidebar.component.scss
  55. 194 0
      src/app/layout/sidebar/sidebar.component.ts
  56. 14 0
      src/app/layout/sidebar/userblock/userblock.component.html
  57. 0 0
      src/app/layout/sidebar/userblock/userblock.component.scss
  58. 42 0
      src/app/layout/sidebar/userblock/userblock.component.ts
  59. 23 0
      src/app/layout/sidebar/userblock/userblock.service.ts
  60. 163 0
      src/app/routes/frame/core/FrameEditComponent.ts
  61. 139 0
      src/app/routes/frame/core/FramePageComponent.ts
  62. 24 0
      src/app/routes/frame/dept/dept.frame.module.ts
  63. 84 0
      src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.html
  64. 0 0
      src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.scss
  65. 109 0
      src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.ts
  66. 51 0
      src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.html
  67. 0 0
      src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.scss
  68. 25 0
      src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.ts
  69. 22 0
      src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.html
  70. 0 0
      src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.scss
  71. 73 0
      src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.ts
  72. 23 0
      src/app/routes/frame/dict/dict.frame.module.ts
  73. 86 0
      src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.html
  74. 0 0
      src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.scss
  75. 60 0
      src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.ts
  76. 40 0
      src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.html
  77. 0 0
      src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.scss
  78. 34 0
      src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.ts
  79. 1 0
      src/app/routes/frame/frame.component.html
  80. 14 0
      src/app/routes/frame/frame.component.ts
  81. 29 0
      src/app/routes/frame/frame.module.ts
  82. 135 0
      src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.html
  83. 0 0
      src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.scss
  84. 70 0
      src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.ts
  85. 98 0
      src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.html
  86. 0 0
      src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.scss
  87. 69 0
      src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.ts
  88. 99 0
      src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.html
  89. 0 0
      src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.scss
  90. 63 0
      src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.ts
  91. 55 0
      src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.html
  92. 0 0
      src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.scss
  93. 31 0
      src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.ts
  94. 57 0
      src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.html
  95. 0 0
      src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.scss
  96. 55 0
      src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.ts
  97. 43 0
      src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.html
  98. 0 0
      src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.scss
  99. 26 0
      src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.ts
  100. 25 0
      src/app/routes/frame/optr/optr.frame.module.ts

+ 13 - 0
.editorconfig

@@ -0,0 +1,13 @@
+# Editor configuration, see http://editorconfig.org
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.md]
+max_line_length = off
+trim_trailing_whitespace = false

+ 39 - 0
.gitignore

@@ -0,0 +1,39 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# compiled output
+/dist
+/tmp
+/out-tsc
+
+# dependencies
+/node_modules
+
+# IDEs and editors
+/.idea
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# IDE - VSCode
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+
+# misc
+/.sass-cache
+/connect.lock
+/coverage
+/libpeerconnection.log
+npm-debug.log
+yarn-error.log
+testem.log
+/typings
+
+# System Files
+.DS_Store
+Thumbs.db

+ 27 - 0
README.md

@@ -0,0 +1,27 @@
+# Ng2angle
+
+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 7.0.4.
+
+## Development server
+
+Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
+
+## Code scaffolding
+
+Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
+
+## Build
+
+Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
+
+## Running unit tests
+
+Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+## Running end-to-end tests
+
+Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
+
+## Further help
+
+To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

+ 166 - 0
angular.json

@@ -0,0 +1,166 @@
+{
+  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+  "version": 1,
+  "newProjectRoot": "projects",
+  "projects": {
+    "hm2soft": {
+      "root": "",
+      "sourceRoot": "src",
+      "projectType": "application",
+      "prefix": "app",
+      "schematics": {
+        "@schematics/angular:component": {
+          "styleext": "scss"
+        }
+      },
+      "architect": {
+        "build": {
+          "builder": "@angular-devkit/build-angular:browser",
+          "options": {
+            "outputPath": "dist",
+            "index": "src/index.html",
+            "main": "src/main.ts",
+            "polyfills": "src/polyfills.ts",
+            "tsConfig": "src/tsconfig.app.json",
+            "assets": [
+              "src/favicon.ico",
+              "src/assets"
+            ],
+            "styles": [
+              "src/app/core/preloader/preloader.scss",
+              "src/styles.scss"
+            ],
+            "scripts": [
+              "node_modules/jquery/dist/jquery.js",
+              "src/app/core/preloader/preloader.js",
+              "node_modules/popper.js/dist/umd/popper.js",
+              "node_modules/chart.js/dist/Chart.bundle.js",
+              "node_modules/bootstrap/js/dist/util.js",
+              "node_modules/bootstrap/js/dist/modal.js",
+              "node_modules/bootstrap/js/dist/dropdown.js",
+              "node_modules/bootstrap/js/dist/tooltip.js",
+              "node_modules/summernote/dist/summernote.js",
+              "node_modules/moment/min/moment-with-locales.min.js",
+
+              "node_modules/echarts/dist/echarts.js"
+            ]
+          },
+          "configurations": {
+            "production": {
+              "fileReplacements": [
+                {
+                  "replace": "src/environments/environment.ts",
+                  "with": "src/environments/environment.prod.ts"
+                }
+              ],
+              "optimization": true,
+              "outputHashing": "all",
+              "sourceMap": false,
+              "extractCss": true,
+              "namedChunks": false,
+              "aot": true,
+              "extractLicenses": true,
+              "vendorChunk": false,
+              "buildOptimizer": true,
+              "budgets": [
+                {
+                  "type": "initial",
+                  "maximumWarning": "5mb",
+                  "maximumError": "10mb"
+                }
+              ]
+            }
+          }
+        },
+        "serve": {
+          "builder": "@angular-devkit/build-angular:dev-server",
+          "options": {
+            "browserTarget": "hm2soft:build"
+          },
+          "configurations": {
+            "production": {
+              "browserTarget": "hm2soft:build:production"
+            }
+          }
+        },
+        "extract-i18n": {
+          "builder": "@angular-devkit/build-angular:extract-i18n",
+          "options": {
+            "browserTarget": "hm2soft:build"
+          }
+        },
+        "test": {
+          "builder": "@angular-devkit/build-angular:karma",
+          "options": {
+            "main": "src/test.ts",
+            "polyfills": "src/polyfills.ts",
+            "tsConfig": "src/tsconfig.spec.json",
+            "karmaConfig": "src/karma.conf.js",
+            "styles": [
+              "src/app/core/preloader/preloader.scss",
+              "src/styles.scss"
+            ],
+            "scripts": [
+              "node_modules/jquery/dist/jquery.js",
+              "src/app/core/preloader/preloader.js",
+              "node_modules/popper.js/dist/umd/popper.js",
+              "node_modules/chart.js/dist/Chart.bundle.js",
+              "node_modules/jqcloud2/dist/jqcloud.js",
+              "node_modules/bootstrap/js/dist/util.js",
+              "node_modules/bootstrap/js/dist/modal.js",
+              "node_modules/bootstrap/js/dist/dropdown.js",
+              "node_modules/bootstrap/js/dist/tooltip.js",
+              "node_modules/summernote/dist/summernote.js",
+              "node_modules/moment/min/moment-with-locales.min.js"
+            ],
+            "assets": [
+              "src/favicon.ico",
+              "src/assets"
+            ]
+          }
+        },
+        "lint": {
+          "builder": "@angular-devkit/build-angular:tslint",
+          "options": {
+            "tsConfig": [
+              "src/tsconfig.app.json",
+              "src/tsconfig.spec.json"
+            ],
+            "exclude": [
+              "**/node_modules/**"
+            ]
+          }
+        }
+      }
+    },
+    "hm2soft-e2e": {
+      "root": "e2e/",
+      "projectType": "application",
+      "prefix": "",
+      "architect": {
+        "e2e": {
+          "builder": "@angular-devkit/build-angular:protractor",
+          "options": {
+            "protractorConfig": "e2e/protractor.conf.js",
+            "devServerTarget": "hm2soft:serve"
+          },
+          "configurations": {
+            "production": {
+              "devServerTarget": "hm2soft:serve:production"
+            }
+          }
+        },
+        "lint": {
+          "builder": "@angular-devkit/build-angular:tslint",
+          "options": {
+            "tsConfig": "e2e/tsconfig.e2e.json",
+            "exclude": [
+              "**/node_modules/**"
+            ]
+          }
+        }
+      }
+    }
+  },
+  "defaultProject": "hm2soft"
+}

+ 28 - 0
e2e/protractor.conf.js

@@ -0,0 +1,28 @@
+// Protractor configuration file, see link for more information
+// https://github.com/angular/protractor/blob/master/lib/config.ts
+
+const { SpecReporter } = require('jasmine-spec-reporter');
+
+exports.config = {
+  allScriptsTimeout: 11000,
+  specs: [
+    './src/**/*.e2e-spec.ts'
+  ],
+  capabilities: {
+    'browserName': 'chrome'
+  },
+  directConnect: true,
+  baseUrl: 'http://localhost:4200/',
+  framework: 'jasmine',
+  jasmineNodeOpts: {
+    showColors: true,
+    defaultTimeoutInterval: 30000,
+    print: function() {}
+  },
+  onPrepare() {
+    require('ts-node').register({
+      project: require('path').join(__dirname, './tsconfig.e2e.json')
+    });
+    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
+  }
+};

+ 14 - 0
e2e/src/app.e2e-spec.ts

@@ -0,0 +1,14 @@
+import { Ng2anglePage } from './app.po';
+
+describe('ng2angle App', function() {
+  let page: Ng2anglePage;
+
+  beforeEach(() => {
+    page = new Ng2anglePage();
+  });
+
+  it('should display Angle in h1 tag', () => {
+    page.navigateTo();
+    expect(page.getParagraphText()).toEqual('Angle');
+  });
+});

+ 11 - 0
e2e/src/app.po.ts

@@ -0,0 +1,11 @@
+import { browser, by, element } from 'protractor';
+
+export class Ng2anglePage {
+    navigateTo() {
+        return browser.get('/');
+    }
+
+    getParagraphText() {
+        return element(by.css('app-root h1')).getText();
+    }
+}

+ 13 - 0
e2e/tsconfig.e2e.json

@@ -0,0 +1,13 @@
+{
+  "extends": "../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "../out-tsc/app",
+    "module": "commonjs",
+    "target": "es5",
+    "types": [
+      "jasmine",
+      "jasminewd2",
+      "node"
+    ]
+  }
+}

+ 32 - 0
modernizr-config.json

@@ -0,0 +1,32 @@
+{
+    "classPrefix": "",
+    "options": [
+        "setClasses"
+    ],
+    "feature-detects": [
+        "css/backgroundposition-shorthand",
+        "css/backgroundposition-xy",
+        "css/backgroundrepeat",
+        "css/backgroundsizecover",
+        "css/borderradius",
+        "css/animations",
+        "css/calc",
+        "css/transforms",
+        "css/transforms3d",
+        "css/transformstylepreserve3d",
+        "css/transitions",
+        "css/flexboxtweener",
+        "css/fontface",
+        "svg",
+        "svg/asimg",
+        "svg/clippaths",
+        "svg/filters",
+        "svg/foreignobject",
+        "svg/inline",
+        "svg/smil",
+        "storage/localstorage",
+        "storage/sessionstorage",
+        "storage/websqldatabase",
+        "css/multiplebgs"
+    ]
+}

+ 10640 - 0
package-lock.json

@@ -0,0 +1,10640 @@
+{
+  "name": "hm2soft",
+  "version": "2.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@angular-devkit/architect": {
+      "version": "0.800.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.800.2.tgz",
+      "integrity": "sha512-251GOQwI3254AtnGWZoHmjOMFcz7h6M3fPmRHpYuuhRPIwZnQCKaszYI7gaP9zR7uArLUwsuPo+YYz8lb6Giwg==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/core": "8.0.2",
+        "rxjs": "6.4.0"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        }
+      }
+    },
+    "@angular-devkit/build-angular": {
+      "version": "0.800.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.800.2.tgz",
+      "integrity": "sha512-RlYPEp5FVKosgzWhbI7llM3lGIxAYuCwEPloeUL4XaDasNe2zmLNUlYDVTrF7GpZRoAgiIejmT0HvvKfEuZNZQ==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/architect": "0.800.2",
+        "@angular-devkit/build-optimizer": "0.800.2",
+        "@angular-devkit/build-webpack": "0.800.2",
+        "@angular-devkit/core": "8.0.2",
+        "@ngtools/webpack": "8.0.2",
+        "ajv": "6.10.0",
+        "autoprefixer": "9.5.1",
+        "browserslist": "4.5.5",
+        "caniuse-api": "3.0.0",
+        "circular-dependency-plugin": "5.0.2",
+        "clean-css": "4.2.1",
+        "copy-webpack-plugin": "5.0.2",
+        "core-js": "3.0.1",
+        "file-loader": "3.0.1",
+        "glob": "7.1.3",
+        "istanbul-instrumenter-loader": "3.0.1",
+        "karma-source-map-support": "1.4.0",
+        "less": "3.9.0",
+        "less-loader": "4.1.0",
+        "license-webpack-plugin": "2.1.1",
+        "loader-utils": "1.2.3",
+        "mini-css-extract-plugin": "0.6.0",
+        "minimatch": "3.0.4",
+        "open": "6.2.0",
+        "parse5": "4.0.0",
+        "postcss": "7.0.14",
+        "postcss-import": "12.0.1",
+        "postcss-loader": "3.0.0",
+        "raw-loader": "1.0.0",
+        "rxjs": "6.4.0",
+        "sass": "1.19.0",
+        "sass-loader": "7.1.0",
+        "semver": "6.0.0",
+        "source-map-loader": "0.2.4",
+        "source-map-support": "0.5.12",
+        "speed-measure-webpack-plugin": "1.3.1",
+        "stats-webpack-plugin": "0.7.0",
+        "style-loader": "0.23.1",
+        "stylus": "0.54.5",
+        "stylus-loader": "3.0.2",
+        "terser-webpack-plugin": "1.2.3",
+        "tree-kill": "1.2.1",
+        "webpack": "4.30.0",
+        "webpack-dev-middleware": "3.6.2",
+        "webpack-dev-server": "3.3.1",
+        "webpack-merge": "4.2.1",
+        "webpack-sources": "1.3.0",
+        "webpack-subresource-integrity": "1.1.0-rc.6",
+        "worker-plugin": "3.1.0"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.0.1.tgz",
+          "integrity": "sha512-sco40rF+2KlE0ROMvydjkrVMMG1vYilP2ALoRXcYR4obqbYIuV3Bg+51GEDW+HF8n7NRA+iaA4qD0nD9lo9mew==",
+          "dev": true
+        },
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        },
+        "semver": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz",
+          "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==",
+          "dev": true
+        }
+      }
+    },
+    "@angular-devkit/build-optimizer": {
+      "version": "0.800.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.800.2.tgz",
+      "integrity": "sha512-A/lX7Fjfeh5PspGURV8fJeOsrIYM/7why7mC6v78zdxaErd4S18wUXJDfndjx3qiKyuq76Uu4cQcS7XfClpb8Q==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "1.2.3",
+        "source-map": "0.5.6",
+        "typescript": "3.4.4",
+        "webpack-sources": "1.3.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.6",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
+          "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
+          "dev": true
+        },
+        "typescript": {
+          "version": "3.4.4",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.4.tgz",
+          "integrity": "sha512-xt5RsIRCEaf6+j9AyOBgvVuAec0i92rgCaS3S+UVf5Z/vF2Hvtsw08wtUTJqp4djwznoAgjSxeCcU4r+CcDBJA==",
+          "dev": true
+        }
+      }
+    },
+    "@angular-devkit/build-webpack": {
+      "version": "0.800.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.800.2.tgz",
+      "integrity": "sha512-Bd/sazcriUTFQCGFDyUkjXSmpn8hRLIyLIXBLAn+5coH4Y4xNy8PXt+hnr6ffwu92h/WnyxKIJi44+5aoUBURA==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/architect": "0.800.2",
+        "@angular-devkit/core": "8.0.2",
+        "rxjs": "6.4.0",
+        "webpack-merge": "4.2.1"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        }
+      }
+    },
+    "@angular-devkit/core": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-8.0.2.tgz",
+      "integrity": "sha512-S2OPYe6Qu7qTS8Q2lzf4qNjXdbN/J2YVnd3wGauMI8Tih5tY/NzUW3h5ds09nRcjsdBDuT0qgf3IMlCZWIABvQ==",
+      "dev": true,
+      "requires": {
+        "ajv": "6.10.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "magic-string": "0.25.2",
+        "rxjs": "6.4.0",
+        "source-map": "0.7.3"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        }
+      }
+    },
+    "@angular-devkit/schematics": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-8.0.2.tgz",
+      "integrity": "sha512-v+g0MOPADJJ5QNNmojCyh2sw1GOzadlbHPdTFqZOm77b2Bi79dRm+yuYMuY6a2nUt7DIcioLRcOFwV8UctajRg==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/core": "8.0.2",
+        "rxjs": "6.4.0"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        }
+      }
+    },
+    "@angular/animations": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-8.0.0.tgz",
+      "integrity": "sha512-hggSRi83rmocLwzrKZtmFcqPdivKSJqp2yiYaiNmJ2yQWJ1JW/Lurypv9H347RWxmwCCwC2kV8embTGbOXIFDQ==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/cli": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-8.0.2.tgz",
+      "integrity": "sha512-xXSCwTKonC6nMqKPDlEFhXjKBu85jVB+KYo2tLU+RKtgFeIF/hTaUWQTvWXRwRsQAfBhB1cwe0oijdljOItTgw==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/architect": "0.800.2",
+        "@angular-devkit/core": "8.0.2",
+        "@angular-devkit/schematics": "8.0.2",
+        "@schematics/angular": "8.0.2",
+        "@schematics/update": "0.800.2",
+        "@yarnpkg/lockfile": "1.1.0",
+        "debug": "^4.1.1",
+        "ini": "1.3.5",
+        "inquirer": "6.3.1",
+        "npm-package-arg": "6.1.0",
+        "open": "6.2.0",
+        "pacote": "9.5.0",
+        "read-package-tree": "5.2.2",
+        "semver": "6.0.0",
+        "symbol-observable": "1.2.0",
+        "universal-analytics": "^0.4.20",
+        "uuid": "^3.3.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "semver": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz",
+          "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==",
+          "dev": true
+        }
+      }
+    },
+    "@angular/common": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/common/-/common-8.0.0.tgz",
+      "integrity": "sha512-iOAJZ0+1zTRHnHE/5G30+4Q66W1pfZkSkxZIXvgijZ+wtuNloYdWNy/IdZ/m7ayBI7A6FsYEhyMUoWz2HVEJNw==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/compiler": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-8.0.0.tgz",
+      "integrity": "sha512-4rKsVFMNykF83tPL1VE1+j9kZ3cWHUsLOAB/VqmF64EcR/GsbjKog2v23rSso5kqUtPiVq/FWGYllW6qMdxtJA==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/compiler-cli": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-8.0.0.tgz",
+      "integrity": "sha512-Z0U0Ih8A7V3J1gq7AXnXbrGAD2ERmz7JbREJJRHDWiUNxIqGQiV3Odo1V8FL5n/cKvLwSYM2Ubvk10gb0+3njA==",
+      "dev": true,
+      "requires": {
+        "canonical-path": "1.0.0",
+        "chokidar": "^2.1.1",
+        "convert-source-map": "^1.5.1",
+        "dependency-graph": "^0.7.2",
+        "magic-string": "^0.25.0",
+        "minimist": "^1.2.0",
+        "reflect-metadata": "^0.1.2",
+        "shelljs": "^0.8.1",
+        "source-map": "^0.6.1",
+        "tslib": "^1.9.0",
+        "yargs": "13.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "chokidar": {
+          "version": "2.1.6",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
+          "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
+          "dev": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "glob-parent": "^3.1.0",
+            "inherits": "^2.0.3",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^4.0.0",
+            "normalize-path": "^3.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.2.1",
+            "upath": "^1.1.1"
+          }
+        },
+        "cliui": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0",
+            "wrap-ansi": "^2.0.0"
+          },
+          "dependencies": {
+            "string-width": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+              "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+              "dev": true,
+              "requires": {
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^4.0.0"
+              }
+            }
+          }
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "normalize-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+          "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "upath": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
+          "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+          "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+          "dev": true,
+          "requires": {
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+              "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+              "dev": true
+            },
+            "is-fullwidth-code-point": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+              "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+              "dev": true,
+              "requires": {
+                "number-is-nan": "^1.0.0"
+              }
+            },
+            "string-width": {
+              "version": "1.0.2",
+              "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+              "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+              "dev": true,
+              "requires": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+              }
+            },
+            "strip-ansi": {
+              "version": "3.0.1",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+              "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^2.0.0"
+              }
+            }
+          }
+        },
+        "yargs": {
+          "version": "13.1.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz",
+          "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==",
+          "dev": true,
+          "requires": {
+            "cliui": "^4.0.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^2.0.1",
+            "os-locale": "^3.1.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^3.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^13.0.0"
+          }
+        }
+      }
+    },
+    "@angular/core": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/core/-/core-8.0.0.tgz",
+      "integrity": "sha512-mrkP1PTzqCmZGLYll+TDyawLXHzi+FcRPqSuRxCmDMthUUE93SLXT2yISDkx9aMPtFKgFr6KfrIkKuCz16BP/g==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/forms": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-8.0.0.tgz",
+      "integrity": "sha512-T6XdG3mALWzvnrN3fA1hAmfwvraiF1SPMWNXgPk2riuMf8CFdoro+tQZ4eo1islHrTTw5QzmqN8JJALfhAG6bg==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/language-service": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-8.0.0.tgz",
+      "integrity": "sha512-vGk14oWroEo6ycO4cooznx57nn2sASmCQ/sdE8UVwySUKl940TsVzijgaGqapTepFof9sMqN77y2G15eRKQeAQ==",
+      "dev": true
+    },
+    "@angular/platform-browser": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-8.0.0.tgz",
+      "integrity": "sha512-fTD+pTMbq+On9Uv3VXiei2lfuX7GX31dngm/Y4yWTFeW6eXy0+7kkfflzpLOb0hykCZvcXzarqCuEBBYNLrrOg==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/platform-browser-dynamic": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-8.0.0.tgz",
+      "integrity": "sha512-dx7W7JoSFbsveexjZ/BPlsXbMDLWVLmRCo7IqLvibMrTbdpaaOCNJIXJk1X+f7JJrQ7SwlZaVkoLCMoDWw6fmA==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@angular/router": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@angular/router/-/router-8.0.0.tgz",
+      "integrity": "sha512-DGUTb8qpndE5m716xh00GxuC8o7qamlqbUruGB+SQD6ynU7s5yLGxtKffxqb1BT63+YewpsVxc2Koruvb1qjDw==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "@babel/code-frame": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
+      "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+      "dev": true,
+      "requires": {
+        "@babel/highlight": "^7.0.0"
+      }
+    },
+    "@babel/highlight": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
+      "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.0",
+        "esutils": "^2.0.2",
+        "js-tokens": "^4.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "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
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "@fortawesome/fontawesome-free": {
+      "version": "5.9.0",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.9.0.tgz",
+      "integrity": "sha512-g795BBEzM/Hq2SYNPm/NQTIp3IWd4eXSH0ds87Na2jnrAUFX3wkyZAI4Gwj9DOaWMuz2/01i8oWI7P7T/XLkhg=="
+    },
+    "@ngtools/webpack": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-8.0.2.tgz",
+      "integrity": "sha512-5P0FHF4p5H/G9xGjOG9meDViXcdW3RPdJa2nX1gGpii3/dhFhmU4pxjKn1Bfs4x+PB9FQQvhSvGIBLNf+B4y5Q==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/core": "8.0.2",
+        "enhanced-resolve": "4.1.0",
+        "rxjs": "6.4.0",
+        "tree-kill": "1.2.1",
+        "webpack-sources": "1.3.0"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        }
+      }
+    },
+    "@schematics/angular": {
+      "version": "8.0.2",
+      "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-8.0.2.tgz",
+      "integrity": "sha512-mN9qsoBVpbY1Q7BP8WaiHsyDv+kl5WrIHw/9OASLrGZcoVY7+oj2CfznVq0XRwvVjDtm6ZFor5ruxLF9dQUOSw==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/core": "8.0.2",
+        "@angular-devkit/schematics": "8.0.2"
+      }
+    },
+    "@schematics/update": {
+      "version": "0.800.2",
+      "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.800.2.tgz",
+      "integrity": "sha512-HPjbzr/LfFLdMzi6zMQK8mPyLw+nt+m7OQsdoeOkFgHkHVfHrKQWcOGt4A0D6keDJ6K2g7W5CsqFR6/GMac7Mg==",
+      "dev": true,
+      "requires": {
+        "@angular-devkit/core": "8.0.2",
+        "@angular-devkit/schematics": "8.0.2",
+        "@yarnpkg/lockfile": "1.1.0",
+        "ini": "1.3.5",
+        "pacote": "9.5.0",
+        "rxjs": "6.4.0",
+        "semver": "6.0.0",
+        "semver-intersect": "1.4.0"
+      },
+      "dependencies": {
+        "rxjs": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz",
+          "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==",
+          "dev": true,
+          "requires": {
+            "tslib": "^1.9.0"
+          }
+        },
+        "semver": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz",
+          "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==",
+          "dev": true
+        }
+      }
+    },
+    "@types/chart.js": {
+      "version": "2.7.53",
+      "resolved": "https://registry.npmjs.org/@types/chart.js/-/chart.js-2.7.53.tgz",
+      "integrity": "sha512-z4j5PWjQff3qGF+5nJIegI5b7drtGA6+XAxoAOINZYkkUuwlmBvjbGtruUAugbaxQkLcCklKZ88dZaPSnFNggg=="
+    },
+    "@types/events": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+      "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+      "dev": true
+    },
+    "@types/glob": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+      "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+      "dev": true,
+      "requires": {
+        "@types/events": "*",
+        "@types/minimatch": "*",
+        "@types/node": "*"
+      }
+    },
+    "@types/jasmine": {
+      "version": "2.8.8",
+      "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.8.tgz",
+      "integrity": "sha512-OJSUxLaxXsjjhob2DBzqzgrkLmukM3+JMpRp0r0E4HTdT1nwDCWhaswjYxazPij6uOdzHCJfNbDjmQ1/rnNbCg==",
+      "dev": true
+    },
+    "@types/jasminewd2": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz",
+      "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==",
+      "dev": true,
+      "requires": {
+        "@types/jasmine": "*"
+      }
+    },
+    "@types/jquery": {
+      "version": "3.3.29",
+      "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz",
+      "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==",
+      "dev": true,
+      "requires": {
+        "@types/sizzle": "*"
+      }
+    },
+    "@types/lodash": {
+      "version": "4.14.118",
+      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.118.tgz",
+      "integrity": "sha512-iiJbKLZbhSa6FYRip/9ZDX6HXhayXLDGY2Fqws9cOkEQ6XeKfaxB0sC541mowZJueYyMnVUmmG+al5/4fCDrgw==",
+      "dev": true
+    },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
+    "@types/node": {
+      "version": "12.0.7",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.7.tgz",
+      "integrity": "sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "0.0.32",
+      "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
+      "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=",
+      "dev": true
+    },
+    "@types/selenium-webdriver": {
+      "version": "3.0.16",
+      "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz",
+      "integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==",
+      "dev": true
+    },
+    "@types/sizzle": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
+      "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==",
+      "dev": true
+    },
+    "@types/source-list-map": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
+      "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
+      "dev": true
+    },
+    "@types/webpack-sources": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz",
+      "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*",
+        "@types/source-list-map": "*",
+        "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==",
+          "dev": true
+        }
+      }
+    },
+    "@webassemblyjs/ast": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
+      "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/helper-module-context": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/wast-parser": "1.8.5"
+      }
+    },
+    "@webassemblyjs/floating-point-hex-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz",
+      "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-api-error": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz",
+      "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-buffer": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz",
+      "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-code-frame": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz",
+      "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/wast-printer": "1.8.5"
+      }
+    },
+    "@webassemblyjs/helper-fsm": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz",
+      "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-module-context": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz",
+      "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "mamacro": "^0.0.3"
+      }
+    },
+    "@webassemblyjs/helper-wasm-bytecode": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz",
+      "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==",
+      "dev": true
+    },
+    "@webassemblyjs/helper-wasm-section": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz",
+      "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5"
+      }
+    },
+    "@webassemblyjs/ieee754": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz",
+      "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
+      "dev": true,
+      "requires": {
+        "@xtuc/ieee754": "^1.2.0"
+      }
+    },
+    "@webassemblyjs/leb128": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz",
+      "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==",
+      "dev": true,
+      "requires": {
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/utf8": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz",
+      "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==",
+      "dev": true
+    },
+    "@webassemblyjs/wasm-edit": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz",
+      "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/helper-wasm-section": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5",
+        "@webassemblyjs/wasm-opt": "1.8.5",
+        "@webassemblyjs/wasm-parser": "1.8.5",
+        "@webassemblyjs/wast-printer": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-gen": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz",
+      "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/ieee754": "1.8.5",
+        "@webassemblyjs/leb128": "1.8.5",
+        "@webassemblyjs/utf8": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-opt": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz",
+      "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-buffer": "1.8.5",
+        "@webassemblyjs/wasm-gen": "1.8.5",
+        "@webassemblyjs/wasm-parser": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wasm-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz",
+      "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-api-error": "1.8.5",
+        "@webassemblyjs/helper-wasm-bytecode": "1.8.5",
+        "@webassemblyjs/ieee754": "1.8.5",
+        "@webassemblyjs/leb128": "1.8.5",
+        "@webassemblyjs/utf8": "1.8.5"
+      }
+    },
+    "@webassemblyjs/wast-parser": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz",
+      "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/floating-point-hex-parser": "1.8.5",
+        "@webassemblyjs/helper-api-error": "1.8.5",
+        "@webassemblyjs/helper-code-frame": "1.8.5",
+        "@webassemblyjs/helper-fsm": "1.8.5",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@webassemblyjs/wast-printer": {
+      "version": "1.8.5",
+      "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz",
+      "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/wast-parser": "1.8.5",
+        "@xtuc/long": "4.2.2"
+      }
+    },
+    "@xtuc/ieee754": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+      "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+      "dev": true
+    },
+    "@xtuc/long": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+      "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+      "dev": true
+    },
+    "@yarnpkg/lockfile": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
+      "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
+      "dev": true
+    },
+    "JSONStream": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+      "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+      "dev": true,
+      "requires": {
+        "jsonparse": "^1.2.0",
+        "through": ">=2.2.7 <3"
+      }
+    },
+    "accepts": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+      "dev": true,
+      "requires": {
+        "mime-types": "~2.1.18",
+        "negotiator": "0.6.1"
+      }
+    },
+    "acorn": {
+      "version": "6.1.1",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
+      "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
+      "dev": true
+    },
+    "acorn-dynamic-import": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz",
+      "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
+      "dev": true
+    },
+    "adm-zip": {
+      "version": "0.4.13",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz",
+      "integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw==",
+      "dev": true
+    },
+    "after": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+      "dev": true
+    },
+    "agent-base": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
+      "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
+      "dev": true,
+      "requires": {
+        "es6-promisify": "^5.0.0"
+      }
+    },
+    "agentkeepalive": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz",
+      "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
+      "dev": true,
+      "requires": {
+        "humanize-ms": "^1.2.1"
+      }
+    },
+    "ajv": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
+      "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
+      "dev": true,
+      "requires": {
+        "fast-deep-equal": "^2.0.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "ajv-errors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+      "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+      "dev": true
+    },
+    "ajv-keywords": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz",
+      "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==",
+      "dev": true
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true
+    },
+    "angular-tree-component": {
+      "version": "8.4.0",
+      "resolved": "https://registry.npmjs.org/angular-tree-component/-/angular-tree-component-8.4.0.tgz",
+      "integrity": "sha512-+3TKGI2Ta0DIfrt2urR6YKDPh7Xv/zuFG3YxWMNAVJY6SPlX9tFT8+pBxzXmcTgI2MDZT7M3Ft6eifQdt4krBw==",
+      "requires": {
+        "lodash": "^4.17.11",
+        "mobx": "^3.6.2",
+        "mobx-angular": "2.1.1"
+      }
+    },
+    "angular2-text-mask": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/angular2-text-mask/-/angular2-text-mask-9.0.0.tgz",
+      "integrity": "sha512-iALcnhJPS1zvX48d86rgUgDe/crX6XfhZrXC4Gdlo2/YwZW7u7KJZY6/b3ieSCIWVq/E6p+wDCzeo3E6leRjDA==",
+      "requires": {
+        "text-mask-core": "^5.0.0"
+      }
+    },
+    "angular2-toaster": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/angular2-toaster/-/angular2-toaster-7.0.0.tgz",
+      "integrity": "sha512-+nKyzg7X9r9knVghyURR63eXpbvErd/Hm7c7rx/v4gfqI7jNAkWHxO1tikVKEQFoD+au6Fu54LOGhEmXb0ECxg=="
+    },
+    "ansi-colors": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+      "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+      "dev": true
+    },
+    "ansi-escapes": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+      "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+      "dev": true
+    },
+    "ansi-html": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+      "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+      "dev": true
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+      "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+      "dev": true,
+      "requires": {
+        "micromatch": "^3.1.4",
+        "normalize-path": "^2.1.1"
+      }
+    },
+    "app-root-path": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz",
+      "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==",
+      "dev": true
+    },
+    "append-transform": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz",
+      "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=",
+      "dev": true,
+      "requires": {
+        "default-require-extensions": "^1.0.0"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+      "dev": true
+    },
+    "arg": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz",
+      "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==",
+      "dev": true
+    },
+    "argparse": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+      "requires": {
+        "sprintf-js": "~1.0.2"
+      }
+    },
+    "aria-query": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz",
+      "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7",
+        "commander": "^2.11.0"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-flatten": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+      "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+      "dev": true,
+      "requires": {
+        "array-uniq": "^1.0.1"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "arraybuffer.slice": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+      "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
+      "dev": true
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "dev": true,
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "assert": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+      "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+      "dev": true,
+      "requires": {
+        "object-assign": "^4.1.1",
+        "util": "0.10.3"
+      },
+      "dependencies": {
+        "inherits": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+          "dev": true
+        },
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+          "dev": true,
+          "requires": {
+            "inherits": "2.0.1"
+          }
+        }
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+      "dev": true
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "ast-types-flow": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+      "dev": true
+    },
+    "async": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+      "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.11"
+      }
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-limiter": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+      "dev": true
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+      "dev": true
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "autoprefixer": {
+      "version": "9.5.1",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.5.1.tgz",
+      "integrity": "sha512-KJSzkStUl3wP0D5sdMlP82Q52JLy5+atf2MHAre48+ckWkXgixmfHyWmA77wFDy6jTHU6mIgXv6hAQ2mf1PjJQ==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.5.4",
+        "caniuse-lite": "^1.0.30000957",
+        "normalize-range": "^0.1.2",
+        "num2fraction": "^1.2.2",
+        "postcss": "^7.0.14",
+        "postcss-value-parser": "^3.3.1"
+      }
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+      "dev": true
+    },
+    "aws4": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+      "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+      "dev": true
+    },
+    "axobject-query": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz",
+      "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7"
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "^1.1.3",
+        "esutils": "^2.0.2",
+        "js-tokens": "^3.0.2"
+      }
+    },
+    "babel-generator": {
+      "version": "6.26.1",
+      "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+      "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+      "dev": true,
+      "requires": {
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "detect-indent": "^4.0.0",
+        "jsesc": "^1.3.0",
+        "lodash": "^4.17.4",
+        "source-map": "^0.5.7",
+        "trim-right": "^1.0.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "babel-messages": {
+      "version": "6.23.0",
+      "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+      "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.22.0"
+      }
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "dev": true,
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "babel-template": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+      "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "babel-traverse": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "lodash": "^4.17.4"
+      }
+    },
+    "babel-traverse": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+      "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+      "dev": true,
+      "requires": {
+        "babel-code-frame": "^6.26.0",
+        "babel-messages": "^6.23.0",
+        "babel-runtime": "^6.26.0",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0",
+        "debug": "^2.6.8",
+        "globals": "^9.18.0",
+        "invariant": "^2.2.2",
+        "lodash": "^4.17.4"
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+      "dev": true
+    },
+    "backo2": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+      "dev": true
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+      "dev": true
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "base64-arraybuffer": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+      "dev": true
+    },
+    "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
+    },
+    "base64id": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+      "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+      "dev": true
+    },
+    "batch": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+      "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+      "dev": true
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "dev": true,
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "better-assert": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+      "dev": true,
+      "requires": {
+        "callsite": "1.0.0"
+      }
+    },
+    "big.js": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+      "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+      "dev": true
+    },
+    "binary-extensions": {
+      "version": "1.13.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz",
+      "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==",
+      "dev": true
+    },
+    "blob": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
+      "dev": true
+    },
+    "blocking-proxy": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-1.0.1.tgz",
+      "integrity": "sha512-KE8NFMZr3mN2E0HcvCgRtX7DjhiIQrwle+nSVJVC/yqFb9+xznHl2ZcoBp2L9qzkI4t4cBFJ1efXF8Dwi132RA==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "bluebird": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz",
+      "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==",
+      "dev": true
+    },
+    "bn.js": {
+      "version": "4.11.8",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+      "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+      "dev": true
+    },
+    "body-parser": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "on-finished": "~2.3.0",
+        "qs": "6.7.0",
+        "raw-body": "2.4.0",
+        "type-is": "~1.6.17"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+          "dev": true
+        },
+        "http-errors": {
+          "version": "1.7.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+          "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+          "dev": true,
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.1",
+            "statuses": ">= 1.5.0 < 2",
+            "toidentifier": "1.0.0"
+          }
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        },
+        "setprototypeof": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+          "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+          "dev": true
+        }
+      }
+    },
+    "bonjour": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+      "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+      "dev": true,
+      "requires": {
+        "array-flatten": "^2.1.0",
+        "deep-equal": "^1.0.1",
+        "dns-equal": "^1.0.0",
+        "dns-txt": "^2.0.2",
+        "multicast-dns": "^6.0.1",
+        "multicast-dns-service-types": "^1.1.0"
+      }
+    },
+    "bootstrap": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+      "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      }
+    },
+    "browserify-sign": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+      "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.1",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.2",
+        "elliptic": "^6.0.0",
+        "inherits": "^2.0.1",
+        "parse-asn1": "^5.0.0"
+      }
+    },
+    "browserify-zlib": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+      "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+      "dev": true,
+      "requires": {
+        "pako": "~1.0.5"
+      }
+    },
+    "browserslist": {
+      "version": "4.5.5",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.5.5.tgz",
+      "integrity": "sha512-0QFO1r/2c792Ohkit5XI8Cm8pDtZxgNl2H6HU4mHrpYz7314pEYcsAVVatM0l/YmxPnEzh9VygXouj4gkFUTKA==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "^1.0.30000960",
+        "electron-to-chromium": "^1.3.124",
+        "node-releases": "^1.1.14"
+      }
+    },
+    "browserstack": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz",
+      "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==",
+      "dev": true,
+      "requires": {
+        "https-proxy-agent": "^2.2.1"
+      }
+    },
+    "buffer": {
+      "version": "4.9.1",
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+      "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+      "dev": true,
+      "requires": {
+        "base64-js": "^1.0.2",
+        "ieee754": "^1.1.4",
+        "isarray": "^1.0.0"
+      }
+    },
+    "buffer-alloc": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+      "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+      "dev": true,
+      "requires": {
+        "buffer-alloc-unsafe": "^1.1.0",
+        "buffer-fill": "^1.0.0"
+      }
+    },
+    "buffer-alloc-unsafe": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+      "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+      "dev": true
+    },
+    "buffer-fill": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+      "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+      "dev": true
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "buffer-indexof": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+      "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+      "dev": true
+    },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+      "dev": true
+    },
+    "builtin-status-codes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+      "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+      "dev": true
+    },
+    "builtins": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz",
+      "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=",
+      "dev": true
+    },
+    "bytes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+      "dev": true
+    },
+    "cacache": {
+      "version": "11.3.2",
+      "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz",
+      "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.3",
+        "chownr": "^1.1.1",
+        "figgy-pudding": "^3.5.1",
+        "glob": "^7.1.3",
+        "graceful-fs": "^4.1.15",
+        "lru-cache": "^5.1.1",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "move-concurrently": "^1.0.1",
+        "promise-inflight": "^1.0.1",
+        "rimraf": "^2.6.2",
+        "ssri": "^6.0.1",
+        "unique-filename": "^1.1.1",
+        "y18n": "^4.0.0"
+      }
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
+    "callsite": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "5.3.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
+    },
+    "caniuse-api": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+      "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+      "dev": true,
+      "requires": {
+        "browserslist": "^4.0.0",
+        "caniuse-lite": "^1.0.0",
+        "lodash.memoize": "^4.1.2",
+        "lodash.uniq": "^4.5.0"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30000974",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz",
+      "integrity": "sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==",
+      "dev": true
+    },
+    "canonical-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz",
+      "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+      "dev": true
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "dev": true,
+      "requires": {
+        "ansi-styles": "^2.2.1",
+        "escape-string-regexp": "^1.0.2",
+        "has-ansi": "^2.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+      "dev": true
+    },
+    "chart.js": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.8.0.tgz",
+      "integrity": "sha512-Di3wUL4BFvqI5FB5K26aQ+hvWh8wnP9A3DWGvXHVkO13D3DSnaSsdZx29cXlEsYKVkn1E2az+ZYFS4t0zi8x0w==",
+      "requires": {
+        "chartjs-color": "^2.1.0",
+        "moment": "^2.10.2"
+      }
+    },
+    "chartjs-color": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.3.0.tgz",
+      "integrity": "sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g==",
+      "requires": {
+        "chartjs-color-string": "^0.6.0",
+        "color-convert": "^0.5.3"
+      },
+      "dependencies": {
+        "color-convert": {
+          "version": "0.5.3",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+          "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+        }
+      }
+    },
+    "chartjs-color-string": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+      "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
+      "requires": {
+        "color-name": "^1.0.0"
+      }
+    },
+    "chokidar": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+      "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+      "dev": true,
+      "requires": {
+        "anymatch": "^2.0.0",
+        "async-each": "^1.0.0",
+        "braces": "^2.3.0",
+        "fsevents": "^1.2.2",
+        "glob-parent": "^3.1.0",
+        "inherits": "^2.0.1",
+        "is-binary-path": "^1.0.0",
+        "is-glob": "^4.0.0",
+        "lodash.debounce": "^4.0.8",
+        "normalize-path": "^2.1.1",
+        "path-is-absolute": "^1.0.0",
+        "readdirp": "^2.0.0",
+        "upath": "^1.0.5"
+      }
+    },
+    "chownr": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
+      "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
+      "dev": true
+    },
+    "chrome-trace-event": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+      "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "circular-dependency-plugin": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.0.2.tgz",
+      "integrity": "sha512-oC7/DVAyfcY3UWKm0sN/oVoDedQDQiw/vIiAnuTWTpE5s0zWf7l3WY417Xw/Fbi/QbAjctAkxgMiS9P0s3zkmA==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "classlist.js": {
+      "version": "1.1.20150312",
+      "resolved": "https://registry.npmjs.org/classlist.js/-/classlist.js-1.1.20150312.tgz",
+      "integrity": "sha1-HXCEL3Ai8I2awIbOaeWyUPLFd4k="
+    },
+    "clean-css": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
+      "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
+      "dev": true,
+      "requires": {
+        "source-map": "~0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "^2.0.0"
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+      "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+      "requires": {
+        "string-width": "^3.1.0",
+        "strip-ansi": "^5.2.0",
+        "wrap-ansi": "^5.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true
+    },
+    "clone-deep": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
+      "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "is-plain-object": "^2.0.4",
+        "kind-of": "^6.0.0",
+        "shallow-clone": "^1.0.0"
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+      "dev": true
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+      "dev": true
+    },
+    "codelyzer": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-5.1.0.tgz",
+      "integrity": "sha512-QiyY2/oDQnYx4mAVEDqr+z9MwrOto18tQFjExiuRChXCy0yvngS5fQpWIxvAGpbOmZFiR1PRTRLbEI71u10maA==",
+      "dev": true,
+      "requires": {
+        "app-root-path": "^2.2.1",
+        "aria-query": "^3.0.0",
+        "axobject-query": "^2.0.2",
+        "css-selector-tokenizer": "^0.7.1",
+        "cssauron": "^1.4.0",
+        "damerau-levenshtein": "^1.0.4",
+        "semver-dsl": "^1.0.1",
+        "source-map": "^0.5.7",
+        "sprintf-js": "^1.1.2"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        },
+        "sprintf-js": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+          "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+          "dev": true
+        }
+      }
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+    },
+    "colors": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+      "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dev": true,
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.17.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+      "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+      "dev": true
+    },
+    "commondir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+      "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+      "dev": true
+    },
+    "component-bind": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+      "dev": true
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "component-inherit": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+      "dev": true
+    },
+    "compressible": {
+      "version": "2.0.17",
+      "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz",
+      "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
+      "dev": true,
+      "requires": {
+        "mime-db": ">= 1.40.0 < 2"
+      },
+      "dependencies": {
+        "mime-db": {
+          "version": "1.40.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+          "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+          "dev": true
+        }
+      }
+    },
+    "compression": {
+      "version": "1.7.4",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.5",
+        "bytes": "3.0.0",
+        "compressible": "~2.0.16",
+        "debug": "2.6.9",
+        "on-headers": "~1.0.2",
+        "safe-buffer": "5.1.2",
+        "vary": "~1.1.2"
+      }
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+      "dev": true
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "connect": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+      "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "finalhandler": "1.1.2",
+        "parseurl": "~1.3.3",
+        "utils-merge": "1.0.1"
+      },
+      "dependencies": {
+        "parseurl": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+          "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+          "dev": true
+        }
+      }
+    },
+    "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",
+      "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+      "dev": true
+    },
+    "console-browserify": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+      "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+      "dev": true,
+      "requires": {
+        "date-now": "^0.1.4"
+      }
+    },
+    "constants-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+      "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+      "dev": true
+    },
+    "content-disposition": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+      "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+      "dev": true
+    },
+    "convert-source-map": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+      "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+      "dev": true
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+      "dev": true
+    },
+    "copy-concurrently": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+      "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "fs-write-stream-atomic": "^1.0.8",
+        "iferr": "^0.1.5",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.0"
+      }
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-webpack-plugin": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.0.2.tgz",
+      "integrity": "sha512-7nC7EynPrnBTtBwwbG1aTqrfNS1aTb9eEjSmQDqFtKAsJrR3uDb+pCDIFT2LzhW+SgGJxQcYzThrmXzzZ720uw==",
+      "dev": true,
+      "requires": {
+        "cacache": "^11.3.1",
+        "find-cache-dir": "^2.0.0",
+        "glob-parent": "^3.1.0",
+        "globby": "^7.1.1",
+        "is-glob": "^4.0.0",
+        "loader-utils": "^1.1.0",
+        "minimatch": "^3.0.4",
+        "normalize-path": "^3.0.0",
+        "p-limit": "^2.1.0",
+        "serialize-javascript": "^1.4.0",
+        "webpack-log": "^2.0.0"
+      },
+      "dependencies": {
+        "normalize-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+          "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+          "dev": true
+        }
+      }
+    },
+    "core-js": {
+      "version": "2.5.4",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.4.tgz",
+      "integrity": "sha1-8si/GB8qgLkvNgEhQpzmOi8K6uA="
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+    },
+    "cosmiconfig": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz",
+      "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==",
+      "dev": true,
+      "requires": {
+        "is-directory": "^0.3.1",
+        "js-yaml": "^3.9.0",
+        "parse-json": "^4.0.0",
+        "require-from-string": "^2.0.1"
+      }
+    },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "cross-spawn": {
+      "version": "6.0.5",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+      "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+      "dev": true,
+      "requires": {
+        "nice-try": "^1.0.4",
+        "path-key": "^2.0.1",
+        "semver": "^5.5.0",
+        "shebang-command": "^1.2.0",
+        "which": "^1.2.9"
+      }
+    },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
+    "css-parse": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz",
+      "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=",
+      "dev": true
+    },
+    "css-selector-tokenizer": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz",
+      "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==",
+      "dev": true,
+      "requires": {
+        "cssesc": "^0.1.0",
+        "fastparse": "^1.1.1",
+        "regexpu-core": "^1.0.0"
+      }
+    },
+    "cssauron": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
+      "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=",
+      "dev": true,
+      "requires": {
+        "through": "X.X.X"
+      }
+    },
+    "cssesc": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+      "dev": true
+    },
+    "custom-event": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+      "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+      "dev": true
+    },
+    "cyclist": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+      "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+      "dev": true
+    },
+    "damerau-levenshtein": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz",
+      "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "date-format": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/date-format/-/date-format-2.1.0.tgz",
+      "integrity": "sha512-bYQuGLeFxhkxNOF3rcMtiZxvCBAquGzZm6oWA1oZ0g2THUzivaRhv8uOhdr19LmoobSOLoIAxeUK2RdbM8IFTA==",
+      "dev": true
+    },
+    "date-now": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+      "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "dev": true,
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "debuglog": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
+      "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=",
+      "dev": true
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-equal": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+      "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=",
+      "dev": true
+    },
+    "default-gateway": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
+      "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
+      "dev": true,
+      "requires": {
+        "execa": "^1.0.0",
+        "ip-regex": "^2.1.0"
+      }
+    },
+    "default-require-extensions": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz",
+      "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=",
+      "dev": true,
+      "requires": {
+        "strip-bom": "^2.0.0"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "del": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+      "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+      "dev": true,
+      "requires": {
+        "@types/glob": "^7.1.1",
+        "globby": "^6.1.0",
+        "is-path-cwd": "^2.0.0",
+        "is-path-in-cwd": "^2.0.0",
+        "p-map": "^2.0.0",
+        "pify": "^4.0.1",
+        "rimraf": "^2.6.3"
+      },
+      "dependencies": {
+        "globby": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+          "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "glob": "^7.0.3",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          },
+          "dependencies": {
+            "pify": {
+              "version": "2.3.0",
+              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+              "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+      "dev": true
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+      "dev": true
+    },
+    "dependency-graph": {
+      "version": "0.7.2",
+      "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz",
+      "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==",
+      "dev": true
+    },
+    "des.js": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+      "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+      "dev": true
+    },
+    "detect-indent": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+      "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+      "dev": true,
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
+    "detect-node": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+      "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+      "dev": true
+    },
+    "dezalgo": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
+      "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
+      "dev": true,
+      "requires": {
+        "asap": "^2.0.0",
+        "wrappy": "1"
+      }
+    },
+    "di": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+      "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+      "dev": true
+    },
+    "diff": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
+      "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==",
+      "dev": true
+    },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      }
+    },
+    "dir-glob": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+      "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+      "dev": true,
+      "requires": {
+        "path-type": "^3.0.0"
+      }
+    },
+    "dns-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+      "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+      "dev": true
+    },
+    "dns-packet": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+      "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.0",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "dns-txt": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+      "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+      "dev": true,
+      "requires": {
+        "buffer-indexof": "^1.0.0"
+      }
+    },
+    "doctrine": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+      "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+      "requires": {
+        "esutils": "^2.0.2"
+      }
+    },
+    "dom-serialize": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+      "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+      "dev": true,
+      "requires": {
+        "custom-event": "~1.0.0",
+        "ent": "~2.2.0",
+        "extend": "^3.0.0",
+        "void-elements": "^2.0.0"
+      }
+    },
+    "domain-browser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+      "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+      "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "dev": true,
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "echarts": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/echarts/-/echarts-4.6.0.tgz",
+      "integrity": "sha512-xKkcr6v9UVOSF+PMuj7Ngt3bnzLwN1sSXWCvpvX+jYb3mePYsZnABq7wGkPac/m0nV653uGHXoHK8DCKCprdNg==",
+      "requires": {
+        "zrender": "4.2.0"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.155",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.155.tgz",
+      "integrity": "sha512-/ci/XgZG8jkLYOgOe3mpJY1onxPPTDY17y7scldhnSjjZqV6VvREG/LvwhRuV7BJbnENFfuDWZkSqlTh4x9ZjQ==",
+      "dev": true
+    },
+    "elliptic": {
+      "version": "6.4.1",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
+      "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      }
+    },
+    "emoji-regex": {
+      "version": "7.0.3",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+      "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+    },
+    "emojis-list": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+      "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+      "dev": true
+    },
+    "encodeurl": {
+      "version": "1.0.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=",
+      "dev": true,
+      "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",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "engine.io": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz",
+      "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.4",
+        "base64id": "1.0.0",
+        "cookie": "0.3.1",
+        "debug": "~3.1.0",
+        "engine.io-parser": "~2.1.0",
+        "ws": "~3.3.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "engine.io-client": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
+      "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "component-inherit": "0.0.3",
+        "debug": "~3.1.0",
+        "engine.io-parser": "~2.1.1",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "parseqs": "0.0.5",
+        "parseuri": "0.0.5",
+        "ws": "~3.3.1",
+        "xmlhttprequest-ssl": "~1.5.4",
+        "yeast": "0.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "engine.io-parser": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
+      "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
+      "dev": true,
+      "requires": {
+        "after": "0.8.2",
+        "arraybuffer.slice": "~0.0.7",
+        "base64-arraybuffer": "0.1.5",
+        "blob": "0.0.5",
+        "has-binary2": "~1.0.2"
+      }
+    },
+    "enhanced-resolve": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz",
+      "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "memory-fs": "^0.4.0",
+        "tapable": "^1.0.0"
+      }
+    },
+    "ent": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+      "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+      "dev": true
+    },
+    "entities": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
+    },
+    "err-code": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz",
+      "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=",
+      "dev": true
+    },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "dev": true,
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "es6-object-assign": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz",
+      "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw="
+    },
+    "es6-promise": {
+      "version": "4.2.8",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
+      "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
+      "dev": true
+    },
+    "es6-promisify": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+      "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+      "dev": true,
+      "requires": {
+        "es6-promise": "^4.0.3"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+      "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+      "dev": true,
+      "requires": {
+        "esrecurse": "^4.1.0",
+        "estraverse": "^4.1.1"
+      }
+    },
+    "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
+    },
+    "esrecurse": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+      "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+      "dev": true,
+      "requires": {
+        "estraverse": "^4.1.0"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+      "dev": true
+    },
+    "eventemitter3": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+      "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+      "dev": true
+    },
+    "events": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz",
+      "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==",
+      "dev": true
+    },
+    "eventsource": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+      "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+      "dev": true,
+      "requires": {
+        "original": "^1.0.0"
+      }
+    },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "execa": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+      "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^6.0.0",
+        "get-stream": "^4.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      }
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "accepts": {
+          "version": "1.3.7",
+          "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+          "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+          "dev": true,
+          "requires": {
+            "mime-types": "~2.1.24",
+            "negotiator": "0.6.2"
+          }
+        },
+        "array-flatten": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+          "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+          "dev": true
+        },
+        "body-parser": {
+          "version": "1.19.0",
+          "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+          "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+          "dev": true,
+          "requires": {
+            "bytes": "3.1.0",
+            "content-type": "~1.0.4",
+            "debug": "2.6.9",
+            "depd": "~1.1.2",
+            "http-errors": "1.7.2",
+            "iconv-lite": "0.4.24",
+            "on-finished": "~2.3.0",
+            "qs": "6.7.0",
+            "raw-body": "2.4.0",
+            "type-is": "~1.6.17"
+          }
+        },
+        "bytes": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+          "dev": true
+        },
+        "cookie": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+          "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+          "dev": true
+        },
+        "http-errors": {
+          "version": "1.7.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+          "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+          "dev": true,
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.1",
+            "statuses": ">= 1.5.0 < 2",
+            "toidentifier": "1.0.0"
+          }
+        },
+        "mime-db": {
+          "version": "1.40.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+          "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.24",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+          "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+          "dev": true,
+          "requires": {
+            "mime-db": "1.40.0"
+          }
+        },
+        "negotiator": {
+          "version": "0.6.2",
+          "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+          "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+          "dev": true
+        },
+        "parseurl": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+          "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+          "dev": true
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+          "dev": true
+        },
+        "range-parser": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+          "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+          "dev": true
+        },
+        "raw-body": {
+          "version": "2.4.0",
+          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+          "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+          "dev": true,
+          "requires": {
+            "bytes": "3.1.0",
+            "http-errors": "1.7.2",
+            "iconv-lite": "0.4.24",
+            "unpipe": "1.0.0"
+          }
+        },
+        "setprototypeof": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+          "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+          "dev": true
+        },
+        "type-is": {
+          "version": "1.6.18",
+          "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+          "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+          "dev": true,
+          "requires": {
+            "media-typer": "0.3.0",
+            "mime-types": "~2.1.24"
+          }
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "dev": true
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "external-editor": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
+      "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+      "dev": true,
+      "requires": {
+        "chardet": "^0.7.0",
+        "iconv-lite": "^0.4.24",
+        "tmp": "^0.0.33"
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+      "dev": true
+    },
+    "fast-deep-equal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+      "dev": true
+    },
+    "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",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+      "dev": true
+    },
+    "fastparse": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+      "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
+      "dev": true
+    },
+    "faye-websocket": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
+      "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
+      "dev": true,
+      "requires": {
+        "websocket-driver": ">=0.5.1"
+      }
+    },
+    "figgy-pudding": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz",
+      "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "^1.0.5"
+      }
+    },
+    "file": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/file/-/file-0.2.2.tgz",
+      "integrity": "sha1-w9/Y+M81Na5FXCtCPC5SY112tNM="
+    },
+    "file-loader": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-3.0.1.tgz",
+      "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.0.2",
+        "schema-utils": "^1.0.0"
+      }
+    },
+    "fileset": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz",
+      "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=",
+      "dev": true,
+      "requires": {
+        "glob": "^7.0.3",
+        "minimatch": "^3.0.3"
+      }
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+      "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "statuses": "~1.5.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "parseurl": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+          "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+          "dev": true
+        }
+      }
+    },
+    "find-cache-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+      "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+      "dev": true,
+      "requires": {
+        "commondir": "^1.0.1",
+        "make-dir": "^2.0.0",
+        "pkg-dir": "^3.0.0"
+      }
+    },
+    "find-up": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+      "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+      "requires": {
+        "locate-path": "^3.0.0"
+      },
+      "dependencies": {
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+          "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
+        }
+      }
+    },
+    "flatted": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
+      "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+      "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.3.6"
+      }
+    },
+    "follow-redirects": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
+      "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
+      "dev": true,
+      "requires": {
+        "debug": "^3.2.6"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        }
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.1"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+      "dev": true
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "dev": true,
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+      "dev": true
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+      "dev": true
+    },
+    "from2": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+      "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0"
+      }
+    },
+    "fs-access": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
+      "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
+      "dev": true,
+      "requires": {
+        "null-check": "^1.0.0"
+      }
+    },
+    "fs-extra": {
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+      "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "jsonfile": "^4.0.0",
+        "universalify": "^0.1.0"
+      }
+    },
+    "fs-minipass": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz",
+      "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==",
+      "dev": true,
+      "requires": {
+        "minipass": "^2.2.1"
+      }
+    },
+    "fs-write-stream-atomic": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+      "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "iferr": "^0.1.5",
+        "imurmurhash": "^0.1.4",
+        "readable-stream": "1 || 2"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+      "dev": true
+    },
+    "fsevents": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz",
+      "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "^2.9.2",
+        "node-pre-gyp": "^0.10.0"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "^1.0.0",
+            "readable-stream": "^2.0.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": 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"
+          }
+        },
+        "chownr": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "^1.0.3",
+            "console-control-strings": "^1.0.0",
+            "has-unicode": "^2.0.0",
+            "object-assign": "^4.1.0",
+            "signal-exit": "^3.0.0",
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1",
+            "wide-align": "^1.1.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "iconv-lite": {
+          "version": "0.4.24",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimatch": "^3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "once": "^1.3.0",
+            "wrappy": "1"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": 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"
+          }
+        },
+        "minizlib": {
+          "version": "1.2.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "needle": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "^2.1.2",
+            "iconv-lite": "^0.4.4",
+            "sax": "^1.2.4"
+          }
+        },
+        "node-pre-gyp": {
+          "version": "0.10.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "^1.0.2",
+            "mkdirp": "^0.5.1",
+            "needle": "^2.2.1",
+            "nopt": "^4.0.1",
+            "npm-packlist": "^1.1.6",
+            "npmlog": "^4.0.2",
+            "rc": "^1.2.7",
+            "rimraf": "^2.6.1",
+            "semver": "^5.3.0",
+            "tar": "^4"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1",
+            "osenv": "^0.1.4"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "npm-packlist": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ignore-walk": "^3.0.1",
+            "npm-bundled": "^1.0.1"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "wrappy": "1"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "^1.0.0",
+            "os-tmpdir": "^1.0.0"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.8",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "^0.6.0",
+            "ini": "~1.3.0",
+            "minimist": "^1.2.0",
+            "strip-json-comments": "~2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "^7.1.3"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.6.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "4.4.8",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chownr": "^1.1.1",
+            "fs-minipass": "^1.2.5",
+            "minipass": "^2.3.4",
+            "minizlib": "^1.1.1",
+            "mkdirp": "^0.5.0",
+            "safe-buffer": "^5.1.2",
+            "yallist": "^3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wide-align": {
+          "version": "1.1.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "^1.0.2 || 2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "yallist": {
+          "version": "3.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "genfun": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz",
+      "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==",
+      "dev": true
+    },
+    "get-caller-file": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
+    },
+    "get-stream": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+      "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+      "dev": true,
+      "requires": {
+        "pump": "^3.0.0"
+      }
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "dev": true,
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+      "dev": true,
+      "requires": {
+        "is-glob": "^3.1.0",
+        "path-dirname": "^1.0.0"
+      },
+      "dependencies": {
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.0"
+          }
+        }
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+      "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+      "dev": true,
+      "requires": {
+        "array-union": "^1.0.1",
+        "dir-glob": "^2.0.0",
+        "glob": "^7.1.2",
+        "ignore": "^3.3.5",
+        "pify": "^3.0.0",
+        "slash": "^1.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.15",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
+    },
+    "handle-thing": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
+      "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==",
+      "dev": true
+    },
+    "handlebars": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.0.tgz",
+      "integrity": "sha512-l2jRuU1NAWK6AW5qqcTATWQJvNPEwkM7NEKSiv/gqOsoSQbVoWyqVEY5GS+XPQ88zLNmqASRpzfdm8d79hJS+w==",
+      "dev": true,
+      "requires": {
+        "async": "^2.5.0",
+        "optimist": "^0.6.1",
+        "source-map": "^0.6.1",
+        "uglify-js": "^3.1.4"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+          "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.17.11"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
+    "har-validator": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "has-binary2": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+      "dev": true,
+      "requires": {
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "dev": true
+        }
+      }
+    },
+    "has-cors": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+      "dev": true
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "hash-base": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+      "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+      "dev": true
+    },
+    "hpack.js": {
+      "version": "2.1.6",
+      "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+      "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "obuf": "^1.0.0",
+        "readable-stream": "^2.0.1",
+        "wbuf": "^1.1.0"
+      }
+    },
+    "html-entities": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
+      "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
+      "dev": true
+    },
+    "http-cache-semantics": {
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+      "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==",
+      "dev": true
+    },
+    "http-deceiver": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+      "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+      "dev": true
+    },
+    "http-errors": {
+      "version": "1.6.3",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+      "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+      "dev": true,
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": ">= 1.4.0 < 2"
+      }
+    },
+    "http-parser-js": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
+      "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==",
+      "dev": true
+    },
+    "http-proxy": {
+      "version": "1.17.0",
+      "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+      "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+      "dev": true,
+      "requires": {
+        "eventemitter3": "^3.0.0",
+        "follow-redirects": "^1.0.0",
+        "requires-port": "^1.0.0"
+      }
+    },
+    "http-proxy-agent": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
+      "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
+      "dev": true,
+      "requires": {
+        "agent-base": "4",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "http-proxy-middleware": {
+      "version": "0.19.1",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+      "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+      "dev": true,
+      "requires": {
+        "http-proxy": "^1.17.0",
+        "is-glob": "^4.0.0",
+        "lodash": "^4.17.11",
+        "micromatch": "^3.1.10"
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "https-browserify": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+      "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+      "dev": true
+    },
+    "https-proxy-agent": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+      "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+      "dev": true,
+      "requires": {
+        "agent-base": "^4.1.0",
+        "debug": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "humanize-ms": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+      "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
+      "dev": true,
+      "requires": {
+        "ms": "^2.0.0"
+      }
+    },
+    "iconv-lite": {
+      "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"
+      }
+    },
+    "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
+    },
+    "iferr": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+      "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "3.3.10",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+      "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+      "dev": true
+    },
+    "ignore-walk": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
+      "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
+      "dev": true,
+      "requires": {
+        "minimatch": "^3.0.4"
+      }
+    },
+    "image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+      "dev": true,
+      "optional": true
+    },
+    "immediate": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+      "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
+      "dev": true
+    },
+    "import-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+      "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+      "dev": true,
+      "requires": {
+        "import-from": "^2.1.0"
+      }
+    },
+    "import-from": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+      "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "import-local": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+      "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+      "dev": true,
+      "requires": {
+        "pkg-dir": "^3.0.0",
+        "resolve-cwd": "^2.0.0"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "indexof": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "6.3.1",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
+      "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "^3.2.0",
+        "chalk": "^2.4.2",
+        "cli-cursor": "^2.1.0",
+        "cli-width": "^2.0.0",
+        "external-editor": "^3.0.3",
+        "figures": "^2.0.0",
+        "lodash": "^4.17.11",
+        "mute-stream": "0.0.7",
+        "run-async": "^2.2.0",
+        "rxjs": "^6.4.0",
+        "string-width": "^2.1.0",
+        "strip-ansi": "^5.1.0",
+        "through": "^2.3.6"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          },
+          "dependencies": {
+            "ansi-regex": {
+              "version": "4.1.0",
+              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+              "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+              "dev": true
+            }
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "internal-ip": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
+      "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+      "dev": true,
+      "requires": {
+        "default-gateway": "^4.2.0",
+        "ipaddr.js": "^1.9.0"
+      }
+    },
+    "interpret": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
+      "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+      "dev": true
+    },
+    "intl": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz",
+      "integrity": "sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94="
+    },
+    "invariant": {
+      "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"
+      }
+    },
+    "invert-kv": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
+      "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA=="
+    },
+    "ip": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+      "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+      "dev": true
+    },
+    "ip-regex": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+      "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+      "dev": true
+    },
+    "ipaddr.js": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+      "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==",
+      "dev": true
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+      "dev": true
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^1.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+      "dev": true
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-directory": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+      "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+      "dev": true
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "dev": true,
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+      "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+    },
+    "is-glob": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+      "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "is-path-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.1.0.tgz",
+      "integrity": "sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw==",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+      "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "^2.1.0"
+      }
+    },
+    "is-path-inside": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+      "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "^1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+      "dev": true
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+      "dev": true
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "is-wsl": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+      "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "isbinaryfile": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
+      "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
+      "dev": true,
+      "requires": {
+        "buffer-alloc": "^1.2.0"
+      }
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+      "dev": true
+    },
+    "istanbul-api": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz",
+      "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==",
+      "dev": true,
+      "requires": {
+        "async": "^2.1.4",
+        "fileset": "^2.0.2",
+        "istanbul-lib-coverage": "^1.2.1",
+        "istanbul-lib-hook": "^1.2.2",
+        "istanbul-lib-instrument": "^1.10.2",
+        "istanbul-lib-report": "^1.1.5",
+        "istanbul-lib-source-maps": "^1.2.6",
+        "istanbul-reports": "^1.5.1",
+        "js-yaml": "^3.7.0",
+        "mkdirp": "^0.5.1",
+        "once": "^1.4.0"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+          "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.17.11"
+          }
+        }
+      }
+    },
+    "istanbul-instrumenter-loader": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz",
+      "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==",
+      "dev": true,
+      "requires": {
+        "convert-source-map": "^1.5.0",
+        "istanbul-lib-instrument": "^1.7.3",
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^0.3.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "5.5.2",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+          "dev": true,
+          "requires": {
+            "co": "^4.6.0",
+            "fast-deep-equal": "^1.0.0",
+            "fast-json-stable-stringify": "^2.0.0",
+            "json-schema-traverse": "^0.3.0"
+          }
+        },
+        "fast-deep-equal": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+          "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+          "dev": true
+        },
+        "json-schema-traverse": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+          "dev": true
+        },
+        "schema-utils": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
+          "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
+          "dev": true,
+          "requires": {
+            "ajv": "^5.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-coverage": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz",
+      "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==",
+      "dev": true
+    },
+    "istanbul-lib-hook": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz",
+      "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==",
+      "dev": true,
+      "requires": {
+        "append-transform": "^0.4.0"
+      }
+    },
+    "istanbul-lib-instrument": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz",
+      "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==",
+      "dev": true,
+      "requires": {
+        "babel-generator": "^6.18.0",
+        "babel-template": "^6.16.0",
+        "babel-traverse": "^6.18.0",
+        "babel-types": "^6.18.0",
+        "babylon": "^6.18.0",
+        "istanbul-lib-coverage": "^1.2.1",
+        "semver": "^5.3.0"
+      }
+    },
+    "istanbul-lib-report": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz",
+      "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==",
+      "dev": true,
+      "requires": {
+        "istanbul-lib-coverage": "^1.2.1",
+        "mkdirp": "^0.5.1",
+        "path-parse": "^1.0.5",
+        "supports-color": "^3.1.2"
+      },
+      "dependencies": {
+        "has-flag": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+          "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "3.2.3",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+          "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+          "dev": true,
+          "requires": {
+            "has-flag": "^1.0.0"
+          }
+        }
+      }
+    },
+    "istanbul-lib-source-maps": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz",
+      "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==",
+      "dev": true,
+      "requires": {
+        "debug": "^3.1.0",
+        "istanbul-lib-coverage": "^1.2.1",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.6.1",
+        "source-map": "^0.5.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "istanbul-reports": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz",
+      "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==",
+      "dev": true,
+      "requires": {
+        "handlebars": "^4.0.3"
+      }
+    },
+    "jasmine": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz",
+      "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=",
+      "dev": true,
+      "requires": {
+        "exit": "^0.1.2",
+        "glob": "^7.0.6",
+        "jasmine-core": "~2.8.0"
+      },
+      "dependencies": {
+        "jasmine-core": {
+          "version": "2.8.0",
+          "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz",
+          "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=",
+          "dev": true
+        }
+      }
+    },
+    "jasmine-core": {
+      "version": "2.99.1",
+      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
+      "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
+      "dev": true
+    },
+    "jasmine-spec-reporter": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz",
+      "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==",
+      "dev": true,
+      "requires": {
+        "colors": "1.1.2"
+      }
+    },
+    "jasminewd2": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz",
+      "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=",
+      "dev": true
+    },
+    "jquery": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
+      "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
+    },
+    "jquery-slimscroll": {
+      "version": "1.3.8",
+      "resolved": "https://registry.npmjs.org/jquery-slimscroll/-/jquery-slimscroll-1.3.8.tgz",
+      "integrity": "sha1-hIHETnpHaHZTkIoo9/cK7WTITjY=",
+      "requires": {
+        "jquery": ">= 1.7"
+      }
+    },
+    "jquery.browser": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/jquery.browser/-/jquery.browser-0.1.0.tgz",
+      "integrity": "sha1-nHKmCV/SgUtER26o9xZne3Kmors="
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+      "dev": true
+    },
+    "js-yaml": {
+      "version": "3.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"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "dev": true
+    },
+    "jsesc": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+      "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+      "dev": true
+    },
+    "json-parse-better-errors": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+      "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+      "dev": true
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+      "dev": true
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
+      "dev": true
+    },
+    "json3": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
+      "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
+      "dev": true
+    },
+    "json5": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+      "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+      "dev": true,
+      "requires": {
+        "minimist": "^1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "jsonfile": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+      "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.6"
+      }
+    },
+    "jsonparse": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+      "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "jszip": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.1.tgz",
+      "integrity": "sha512-iCMBbo4eE5rb1VCpm5qXOAaUiRKRUKiItn8ah2YQQx9qymmSAY98eyQfioChEYcVQLh0zxJ3wS4A0mh90AVPvw==",
+      "dev": true,
+      "requires": {
+        "lie": "~3.3.0",
+        "pako": "~1.0.2",
+        "readable-stream": "~2.3.6",
+        "set-immediate-shim": "~1.0.1"
+      }
+    },
+    "karma": {
+      "version": "4.4.1",
+      "resolved": "https://registry.npmjs.org/karma/-/karma-4.4.1.tgz",
+      "integrity": "sha512-L5SIaXEYqzrh6b1wqYC42tNsFMx2PWuxky84pK9coK09MvmL7mxii3G3bZBh/0rvD27lqDd0le9jyhzvwif73A==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.3.0",
+        "body-parser": "^1.16.1",
+        "braces": "^3.0.2",
+        "chokidar": "^3.0.0",
+        "colors": "^1.1.0",
+        "connect": "^3.6.0",
+        "di": "^0.0.1",
+        "dom-serialize": "^2.2.0",
+        "flatted": "^2.0.0",
+        "glob": "^7.1.1",
+        "graceful-fs": "^4.1.2",
+        "http-proxy": "^1.13.0",
+        "isbinaryfile": "^3.0.0",
+        "lodash": "^4.17.14",
+        "log4js": "^4.0.0",
+        "mime": "^2.3.1",
+        "minimatch": "^3.0.2",
+        "optimist": "^0.6.1",
+        "qjobs": "^1.1.4",
+        "range-parser": "^1.2.0",
+        "rimraf": "^2.6.0",
+        "safe-buffer": "^5.0.1",
+        "socket.io": "2.1.1",
+        "source-map": "^0.6.1",
+        "tmp": "0.0.33",
+        "useragent": "2.3.0"
+      },
+      "dependencies": {
+        "anymatch": {
+          "version": "3.1.1",
+          "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+          "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+          "dev": true,
+          "requires": {
+            "normalize-path": "^3.0.0",
+            "picomatch": "^2.0.4"
+          }
+        },
+        "binary-extensions": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+          "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+          "dev": true
+        },
+        "braces": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+          "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+          "dev": true,
+          "requires": {
+            "fill-range": "^7.0.1"
+          }
+        },
+        "chokidar": {
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+          "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+          "dev": true,
+          "requires": {
+            "anymatch": "~3.1.1",
+            "braces": "~3.0.2",
+            "fsevents": "~2.1.1",
+            "glob-parent": "~5.1.0",
+            "is-binary-path": "~2.1.0",
+            "is-glob": "~4.0.1",
+            "normalize-path": "~3.0.0",
+            "readdirp": "~3.2.0"
+          }
+        },
+        "fill-range": {
+          "version": "7.0.1",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+          "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+          "dev": true,
+          "requires": {
+            "to-regex-range": "^5.0.1"
+          }
+        },
+        "fsevents": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
+          "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+          "dev": true,
+          "optional": true
+        },
+        "glob-parent": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+          "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.1"
+          }
+        },
+        "is-binary-path": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+          "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+          "dev": true,
+          "requires": {
+            "binary-extensions": "^2.0.0"
+          }
+        },
+        "is-glob": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+          "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "7.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+          "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+          "dev": true
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "mime": {
+          "version": "2.4.4",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
+          "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
+          "dev": true
+        },
+        "normalize-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+          "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+          "dev": true
+        },
+        "readdirp": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
+          "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
+          "dev": true,
+          "requires": {
+            "picomatch": "^2.0.4"
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "to-regex-range": {
+          "version": "5.0.1",
+          "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+          "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+          "dev": true,
+          "requires": {
+            "is-number": "^7.0.0"
+          }
+        }
+      }
+    },
+    "karma-chrome-launcher": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
+      "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
+      "dev": true,
+      "requires": {
+        "fs-access": "^1.0.0",
+        "which": "^1.2.1"
+      }
+    },
+    "karma-cli": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz",
+      "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.1.6"
+      }
+    },
+    "karma-coverage-istanbul-reporter": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-2.0.1.tgz",
+      "integrity": "sha512-UcgrHkFehI5+ivMouD8NH/UOHiX4oCAtwaANylzPFdcAuD52fnCUuelacq2gh8tZ4ydhU3+xiXofSq7j5Ehygw==",
+      "dev": true,
+      "requires": {
+        "istanbul-api": "^1.3.1",
+        "minimatch": "^3.0.4"
+      }
+    },
+    "karma-jasmine": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.2.tgz",
+      "integrity": "sha1-OU8rJf+0pkS5rabyLUQ+L9CIhsM=",
+      "dev": true
+    },
+    "karma-jasmine-html-reporter": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz",
+      "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=",
+      "dev": true,
+      "requires": {
+        "karma-jasmine": "^1.0.2"
+      }
+    },
+    "karma-read-json": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/karma-read-json/-/karma-read-json-1.1.0.tgz",
+      "integrity": "sha1-4M40XFrmOKNqWgXcGmoELczaseQ=",
+      "dev": true
+    },
+    "karma-source-map-support": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz",
+      "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==",
+      "dev": true,
+      "requires": {
+        "source-map-support": "^0.5.5"
+      }
+    },
+    "killable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+      "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+      "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+      "dev": true
+    },
+    "lcid": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
+      "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
+      "requires": {
+        "invert-kv": "^2.0.0"
+      }
+    },
+    "less": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/less/-/less-3.9.0.tgz",
+      "integrity": "sha512-31CmtPEZraNUtuUREYjSqRkeETFdyEHSEPAGq4erDlUXtda7pzNmctdljdIagSb589d/qXGWiiP31R5JVf+v0w==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.2",
+        "errno": "^0.1.1",
+        "graceful-fs": "^4.1.2",
+        "image-size": "~0.5.0",
+        "mime": "^1.4.1",
+        "mkdirp": "^0.5.0",
+        "promise": "^7.1.1",
+        "request": "^2.83.0",
+        "source-map": "~0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "less-loader": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz",
+      "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.1",
+        "loader-utils": "^1.1.0",
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "license-webpack-plugin": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.1.tgz",
+      "integrity": "sha512-TiarZIg5vkQ2rGdYJn2+5YxO/zqlqjpK5IVglr7OfmrN1sBCakS+PQrsP2uC5gtve1ZDb9WMSUMlmHDQ0FoW4w==",
+      "dev": true,
+      "requires": {
+        "@types/webpack-sources": "^0.1.5",
+        "webpack-sources": "^1.2.0"
+      }
+    },
+    "lie": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+      "dev": true,
+      "requires": {
+        "immediate": "~3.0.5"
+      }
+    },
+    "linkify-it": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
+      "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
+      "requires": {
+        "uc.micro": "^1.0.1"
+      }
+    },
+    "loader-runner": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+      "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+      "dev": true
+    },
+    "loader-utils": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
+      "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
+      "dev": true,
+      "requires": {
+        "big.js": "^5.2.2",
+        "emojis-list": "^2.0.0",
+        "json5": "^1.0.1"
+      }
+    },
+    "loaders.css": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/loaders.css/-/loaders.css-0.1.2.tgz",
+      "integrity": "sha1-Op+0NybHMzSjgUKvnQYpAZtlh0M=",
+      "dev": true
+    },
+    "lodash": {
+      "version": "4.17.11",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+      "dev": true
+    },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "dev": true
+    },
+    "lodash.memoize": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+      "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+      "dev": true
+    },
+    "lodash.tail": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
+      "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
+      "dev": true
+    },
+    "lodash.uniq": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+      "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+      "dev": true
+    },
+    "log4js": {
+      "version": "4.5.1",
+      "resolved": "https://registry.npmjs.org/log4js/-/log4js-4.5.1.tgz",
+      "integrity": "sha512-EEEgFcE9bLgaYUKuozyFfytQM2wDHtXn4tAN41pkaxpNjAykv11GVdeI4tHtmPWW4Xrgh9R/2d7XYghDVjbKKw==",
+      "dev": true,
+      "requires": {
+        "date-format": "^2.0.0",
+        "debug": "^4.1.1",
+        "flatted": "^2.0.0",
+        "rfdc": "^1.1.4",
+        "streamroller": "^1.0.6"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "loglevel": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.2.tgz",
+      "integrity": "sha512-Jt2MHrCNdtIe1W6co3tF5KXGRkzF+TYffiQstfXa04mrss9IKXzAAXYWak8LbZseAQY03sH2GzMCMU0ZOUc9bg==",
+      "dev": true
+    },
+    "loose-envify": {
+      "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"
+      }
+    },
+    "lru-cache": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+      "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
+      "requires": {
+        "yallist": "^3.0.2"
+      }
+    },
+    "magic-string": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz",
+      "integrity": "sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==",
+      "dev": true,
+      "requires": {
+        "sourcemap-codec": "^1.4.4"
+      }
+    },
+    "make-dir": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+      "dev": true,
+      "requires": {
+        "pify": "^4.0.1",
+        "semver": "^5.6.0"
+      }
+    },
+    "make-error": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
+      "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
+      "dev": true
+    },
+    "make-fetch-happen": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz",
+      "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==",
+      "dev": true,
+      "requires": {
+        "agentkeepalive": "^3.4.1",
+        "cacache": "^11.0.1",
+        "http-cache-semantics": "^3.8.1",
+        "http-proxy-agent": "^2.1.0",
+        "https-proxy-agent": "^2.2.1",
+        "lru-cache": "^4.1.2",
+        "mississippi": "^3.0.0",
+        "node-fetch-npm": "^2.0.2",
+        "promise-retry": "^1.1.1",
+        "socks-proxy-agent": "^4.0.0",
+        "ssri": "^6.0.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "mamacro": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz",
+      "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==",
+      "dev": true
+    },
+    "map-age-cleaner": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
+      "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
+      "requires": {
+        "p-defer": "^1.0.0"
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "markdown-it": {
+      "version": "8.4.2",
+      "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
+      "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
+      "requires": {
+        "argparse": "^1.0.7",
+        "entities": "~1.1.1",
+        "linkify-it": "^2.0.0",
+        "mdurl": "^1.0.1",
+        "uc.micro": "^1.0.5"
+      }
+    },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "mdurl": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+      "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+      "dev": true
+    },
+    "mem": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz",
+      "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==",
+      "requires": {
+        "map-age-cleaner": "^0.1.1",
+        "mimic-fn": "^1.0.0",
+        "p-is-promise": "^2.0.0"
+      }
+    },
+    "memory-fs": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+      "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+      "requires": {
+        "errno": "^0.1.3",
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+      "dev": true
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+      "dev": true
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
+      }
+    },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      }
+    },
+    "mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.37.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+      "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==",
+      "dev": true
+    },
+    "mime-types": {
+      "version": "2.1.21",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+      "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+      "dev": true,
+      "requires": {
+        "mime-db": "~1.37.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+      "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
+    },
+    "mini-css-extract-plugin": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.6.0.tgz",
+      "integrity": "sha512-79q5P7YGI6rdnVyIAV4NXpBQJFWdkzJxCim3Kog4078fM0piAaFlwocqbejdWtLW1cEzCexPrh6EdyFsPgVdAw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "normalize-url": "^2.0.1",
+        "schema-utils": "^1.0.0",
+        "webpack-sources": "^1.1.0"
+      }
+    },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "dev": true,
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+    },
+    "minipass": {
+      "version": "2.3.5",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
+      "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.0"
+      }
+    },
+    "minizlib": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
+      "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
+      "dev": true,
+      "requires": {
+        "minipass": "^2.2.1"
+      }
+    },
+    "mississippi": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+      "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.5.0",
+        "duplexify": "^3.4.2",
+        "end-of-stream": "^1.1.0",
+        "flush-write-stream": "^1.0.0",
+        "from2": "^2.1.0",
+        "parallel-transform": "^1.1.0",
+        "pump": "^3.0.0",
+        "pumpify": "^1.3.3",
+        "stream-each": "^1.1.0",
+        "through2": "^2.0.0"
+      }
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mixin-object": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
+      "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
+      "dev": true,
+      "requires": {
+        "for-in": "^0.1.3",
+        "is-extendable": "^0.1.1"
+      },
+      "dependencies": {
+        "for-in": {
+          "version": "0.1.8",
+          "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
+          "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
+          "dev": true
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "mobx": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/mobx/-/mobx-3.6.2.tgz",
+      "integrity": "sha512-Dq3boJFLpZEvuh5a/MbHLUIyN9XobKWIb0dBfkNOJffNkE3vtuY0C9kSDVpfH8BB0BPkVw8g22qCv7d05LEhKg=="
+    },
+    "mobx-angular": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/mobx-angular/-/mobx-angular-2.1.1.tgz",
+      "integrity": "sha1-1eNlOayyABht1aEXCAa0d2uai4g="
+    },
+    "modernizr": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/modernizr/-/modernizr-3.7.1.tgz",
+      "integrity": "sha512-pewTfEGiY5pHRnJNKFALn/nkYpWmEOtZ+iRMzQUjexkOum3X4v+xAZ9AqgXdjnDBh37HNCDP6ieq68NGPYvkTA==",
+      "requires": {
+        "doctrine": "^3.0.0",
+        "file": "^0.2.2",
+        "lodash": "^4.17.11",
+        "markdown-it": "^8.4.2",
+        "mkdirp": "^0.5.1",
+        "requirejs": "^2.3.6",
+        "yargs": "^13.2.1"
+      }
+    },
+    "moment": {
+      "version": "2.24.0",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+      "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+    },
+    "move-concurrently": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+      "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1",
+        "copy-concurrently": "^1.0.0",
+        "fs-write-stream-atomic": "^1.0.8",
+        "mkdirp": "^0.5.1",
+        "rimraf": "^2.5.4",
+        "run-queue": "^1.0.3"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+      "dev": true
+    },
+    "multicast-dns": {
+      "version": "6.2.3",
+      "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+      "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+      "dev": true,
+      "requires": {
+        "dns-packet": "^1.3.1",
+        "thunky": "^1.0.2"
+      }
+    },
+    "multicast-dns-service-types": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+      "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+      "dev": true
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.12.1",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz",
+      "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==",
+      "dev": true,
+      "optional": true
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      }
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+      "dev": true
+    },
+    "neo-async": {
+      "version": "2.6.1",
+      "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+      "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+      "dev": true
+    },
+    "ng2-charts": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/ng2-charts/-/ng2-charts-2.3.0.tgz",
+      "integrity": "sha512-D5K7OqF0m5lOBYvNOsraoEo4OPHja9zfGNj+HWy2nUcP0LP2s+Y/QaQlkG/1rHlwXq9HPm8rLxzSutA0eLHxGQ==",
+      "requires": {
+        "@types/chart.js": "^2.7.48",
+        "lodash": "^4.17.11",
+        "tslib": "^1.9.0"
+      }
+    },
+    "ng2-dnd": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/ng2-dnd/-/ng2-dnd-5.0.2.tgz",
+      "integrity": "sha512-5mWWBePwvEPsNd/HkdbD543Q9mPyJofL6zkNydl8/Ah3qrrvZT2DaEPbknY08OgkXpI2qUGksc01OzzVlRQ9dQ=="
+    },
+    "ng2-file-upload": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/ng2-file-upload/-/ng2-file-upload-1.3.0.tgz",
+      "integrity": "sha512-Pudxik6LWYsT8hNiEW7RfjgGWAnvfQywxwJYMdt1snTUe+KnlRc/QqPv3QEQW6plXTanuLkYz/TbqilSfSHOsw=="
+    },
+    "ng2-img-cropper": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/ng2-img-cropper/-/ng2-img-cropper-0.9.0.tgz",
+      "integrity": "sha1-MFM35mnE5a3IdtYo3K4Lyk0Q0cM="
+    },
+    "ng2-material-dropdown": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/ng2-material-dropdown/-/ng2-material-dropdown-0.10.1.tgz",
+      "integrity": "sha512-dOmk4+T6Rbtk60Un7sxOOFU546z5JEYupSL+RiG0/rN4DmJvxPp297AvA2Qm9LSMNszUZMi55cRzj79zQYu85g==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ngx-bootstrap": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-4.3.0.tgz",
+      "integrity": "sha512-ZPS6V2yLEeqB/7KIlVohS8qUdtFa1bgUB/sSPWRcXqOWU3EKhORetZoXG6m2F5ILYDe5hwQvBEjdHPlEz2piOg=="
+    },
+    "ngx-color-picker": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/ngx-color-picker/-/ngx-color-picker-8.0.0.tgz",
+      "integrity": "sha512-0VN+tC/rz/4FLI2SBgvzA7CPhFI6gBGcIar5Kf/3xnUjHDBcCecM0wVHYpgnkA7kmw2Vzwnu/NSDm35vmnj1yw=="
+    },
+    "ngx-cookie-service": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-2.3.0.tgz",
+      "integrity": "sha512-Cegg6ifVuAwhsdrj0sGDyS9lg2o/Uc6FkR8HLcI40rpNMu5tzMd8w23cUiB81a8jDUr/MC44f1S+G6zmWmoy0A=="
+    },
+    "ngx-echarts": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-4.2.2.tgz",
+      "integrity": "sha512-iLxOFnfKhUYP8Qw22AUY2ugSEd1Uvt6AeYhiaSqpg/G6NDmM/NwpdLt+fGAjax2aY7e94ORuwhXnl2gxtNzt7Q==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ngx-infinite-scroll": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-7.2.0.tgz",
+      "integrity": "sha512-EcqjKpU1ukRV3YXOW8cTVtbzPpa9UPaRtYBCg0ZQH3ceCDm+xzLbd4pXy6oKAIN4zN1r/pyGuf5XOJkA8vr6yg==",
+      "requires": {
+        "opencollective-postinstall": "^2.0.2"
+      }
+    },
+    "ngx-loading": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/ngx-loading/-/ngx-loading-3.0.1.tgz",
+      "integrity": "sha512-tiBeQt9PfT31TkN6cg0Wot+r1rDTq6WCI6yiJas7Sqx5xrqun/x/zDBz9R/hCfPcgWNR3t/0GjRrKEj68eDVXw==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ngx-order-pipe": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/ngx-order-pipe/-/ngx-order-pipe-2.0.4.tgz",
+      "integrity": "sha512-ugQ/f2cl5sYLDBSL1XMPflpla9kyqJv2r0zYKhlRH+P+ay4mpyW5PYQUfveN7Aaqzfot0HMwN99k/cGXcKKWNw==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ngx-select-ex": {
+      "version": "3.6.10",
+      "resolved": "https://registry.npmjs.org/ngx-select-ex/-/ngx-select-ex-3.6.10.tgz",
+      "integrity": "sha512-nttHrzeXEt/zpZBx6xvs+sH2v/KxJoygujgS38U0M+xlDe9lPGOeiV3zaMRAX5ZWONCn42o1rcUmbfistWU41g==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "ngx-viewer": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/ngx-viewer/-/ngx-viewer-1.0.5.tgz",
+      "integrity": "sha512-0iFv83UhN2QhfFgjJWNKxFdNTgnrK3FftcwD+1yd368BWfApu0vTvVZwNDC669r42JCpCHMAVQxcFn7k32oXug==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "nice-try": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+      "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+    },
+    "node-fetch-npm": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz",
+      "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==",
+      "dev": true,
+      "requires": {
+        "encoding": "^0.1.11",
+        "json-parse-better-errors": "^1.0.0",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "node-forge": {
+      "version": "0.7.5",
+      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
+      "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==",
+      "dev": true
+    },
+    "node-libs-browser": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz",
+      "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==",
+      "dev": true,
+      "requires": {
+        "assert": "^1.1.1",
+        "browserify-zlib": "^0.2.0",
+        "buffer": "^4.3.0",
+        "console-browserify": "^1.1.0",
+        "constants-browserify": "^1.0.0",
+        "crypto-browserify": "^3.11.0",
+        "domain-browser": "^1.1.1",
+        "events": "^3.0.0",
+        "https-browserify": "^1.0.0",
+        "os-browserify": "^0.3.0",
+        "path-browserify": "0.0.0",
+        "process": "^0.11.10",
+        "punycode": "^1.2.4",
+        "querystring-es3": "^0.2.0",
+        "readable-stream": "^2.3.3",
+        "stream-browserify": "^2.0.1",
+        "stream-http": "^2.7.2",
+        "string_decoder": "^1.0.0",
+        "timers-browserify": "^2.0.4",
+        "tty-browserify": "0.0.0",
+        "url": "^0.11.0",
+        "util": "^0.11.0",
+        "vm-browserify": "0.0.4"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "node-releases": {
+      "version": "1.1.23",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz",
+      "integrity": "sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==",
+      "dev": true,
+      "requires": {
+        "semver": "^5.3.0"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "^2.1.4",
+        "resolve": "^1.10.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "^1.0.1"
+      }
+    },
+    "normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "dev": true
+    },
+    "normalize-url": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+      "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+      "dev": true,
+      "requires": {
+        "prepend-http": "^2.0.0",
+        "query-string": "^5.0.1",
+        "sort-keys": "^2.0.0"
+      }
+    },
+    "npm-bundled": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz",
+      "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
+      "dev": true
+    },
+    "npm-package-arg": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz",
+      "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==",
+      "dev": true,
+      "requires": {
+        "hosted-git-info": "^2.6.0",
+        "osenv": "^0.1.5",
+        "semver": "^5.5.0",
+        "validate-npm-package-name": "^3.0.0"
+      }
+    },
+    "npm-packlist": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz",
+      "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
+      "dev": true,
+      "requires": {
+        "ignore-walk": "^3.0.1",
+        "npm-bundled": "^1.0.1"
+      }
+    },
+    "npm-pick-manifest": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz",
+      "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1",
+        "npm-package-arg": "^6.0.0",
+        "semver": "^5.4.1"
+      }
+    },
+    "npm-registry-fetch": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz",
+      "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==",
+      "dev": true,
+      "requires": {
+        "JSONStream": "^1.3.4",
+        "bluebird": "^3.5.1",
+        "figgy-pudding": "^3.4.1",
+        "lru-cache": "^4.1.3",
+        "make-fetch-happen": "^4.0.1",
+        "npm-package-arg": "^6.1.0"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "null-check": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
+      "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
+      "dev": true
+    },
+    "num2fraction": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+      "dev": true
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+      "dev": true
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+      "dev": true
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
+    },
+    "object-component": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+      "dev": true
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "obuf": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+      "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+      "dev": true
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "dev": true,
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "on-headers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+      "dev": true
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "^1.0.0"
+      }
+    },
+    "open": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/open/-/open-6.2.0.tgz",
+      "integrity": "sha512-Vxf6HJkwrqmvh9UAID3MnMYXntbTxKLOSfOnO7LJdzPf3NE3KQYFNV0/Lcz2VAndbRFil58XVCyh8tiX11fiYw==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "^1.1.0"
+      }
+    },
+    "opencollective-postinstall": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz",
+      "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw=="
+    },
+    "opn": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+      "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+      "dev": true,
+      "requires": {
+        "is-wsl": "^1.1.0"
+      }
+    },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "~0.0.1",
+        "wordwrap": "~0.0.2"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+          "dev": true
+        }
+      }
+    },
+    "original": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
+      "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+      "dev": true,
+      "requires": {
+        "url-parse": "^1.4.3"
+      }
+    },
+    "os-browserify": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+      "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+      "dev": true
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+      "dev": true
+    },
+    "os-locale": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
+      "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
+      "requires": {
+        "execa": "^1.0.0",
+        "lcid": "^2.0.0",
+        "mem": "^4.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "requires": {
+            "nice-try": "^1.0.4",
+            "path-key": "^2.0.1",
+            "semver": "^5.5.0",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        },
+        "execa": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+          "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+          "requires": {
+            "cross-spawn": "^6.0.0",
+            "get-stream": "^4.0.0",
+            "is-stream": "^1.1.0",
+            "npm-run-path": "^2.0.0",
+            "p-finally": "^1.0.0",
+            "signal-exit": "^3.0.0",
+            "strip-eof": "^1.0.0"
+          }
+        },
+        "get-stream": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+          "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+          "requires": {
+            "pump": "^3.0.0"
+          }
+        },
+        "pump": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+          "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+      "dev": true
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+      "dev": true,
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "p-defer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
+      "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+    },
+    "p-is-promise": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz",
+      "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg=="
+    },
+    "p-limit": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+      "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+      "dev": true,
+      "requires": {
+        "p-try": "^2.0.0"
+      }
+    },
+    "p-map": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+      "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+      "dev": true
+    },
+    "p-try": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+      "dev": true
+    },
+    "pacote": {
+      "version": "9.5.0",
+      "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.5.0.tgz",
+      "integrity": "sha512-aUplXozRbzhaJO48FaaeClmN+2Mwt741MC6M3bevIGZwdCaP7frXzbUOfOWa91FPHoLITzG0hYaKY363lxO3bg==",
+      "dev": true,
+      "requires": {
+        "bluebird": "^3.5.3",
+        "cacache": "^11.3.2",
+        "figgy-pudding": "^3.5.1",
+        "get-stream": "^4.1.0",
+        "glob": "^7.1.3",
+        "lru-cache": "^5.1.1",
+        "make-fetch-happen": "^4.0.1",
+        "minimatch": "^3.0.4",
+        "minipass": "^2.3.5",
+        "mississippi": "^3.0.0",
+        "mkdirp": "^0.5.1",
+        "normalize-package-data": "^2.4.0",
+        "npm-package-arg": "^6.1.0",
+        "npm-packlist": "^1.1.12",
+        "npm-pick-manifest": "^2.2.3",
+        "npm-registry-fetch": "^3.8.0",
+        "osenv": "^0.1.5",
+        "promise-inflight": "^1.0.1",
+        "promise-retry": "^1.1.1",
+        "protoduck": "^5.0.1",
+        "rimraf": "^2.6.2",
+        "safe-buffer": "^5.1.2",
+        "semver": "^5.6.0",
+        "ssri": "^6.0.1",
+        "tar": "^4.4.8",
+        "unique-filename": "^1.1.1",
+        "which": "^1.3.1"
+      }
+    },
+    "pako": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
+      "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==",
+      "dev": true
+    },
+    "parallel-transform": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+      "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
+      "dev": true,
+      "requires": {
+        "cyclist": "~0.2.2",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.1.5"
+      }
+    },
+    "parse-asn1": {
+      "version": "5.1.4",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
+      "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^4.0.0",
+        "browserify-aes": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
+    "parse-json": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+      "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+      "dev": true,
+      "requires": {
+        "error-ex": "^1.3.1",
+        "json-parse-better-errors": "^1.0.1"
+      }
+    },
+    "parse5": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+      "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+      "dev": true
+    },
+    "parseqs": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+      "dev": true,
+      "requires": {
+        "better-assert": "~1.0.0"
+      }
+    },
+    "parseuri": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+      "dev": true,
+      "requires": {
+        "better-assert": "~1.0.0"
+      }
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+      "dev": true
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+      "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+      "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+      "dev": true
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+      "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+      "dev": true,
+      "requires": {
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "pbkdf2": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+      "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
+    "picomatch": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz",
+      "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==",
+      "dev": true
+    },
+    "pify": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+      "dev": true
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+      "dev": true
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "dev": true,
+      "requires": {
+        "pinkie": "^2.0.0"
+      }
+    },
+    "pkg-dir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+      "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+      "dev": true,
+      "requires": {
+        "find-up": "^3.0.0"
+      }
+    },
+    "popper.js": {
+      "version": "1.15.0",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz",
+      "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA=="
+    },
+    "portfinder": {
+      "version": "1.0.20",
+      "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
+      "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==",
+      "dev": true,
+      "requires": {
+        "async": "^1.5.2",
+        "debug": "^2.2.0",
+        "mkdirp": "0.5.x"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.5.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+          "dev": true
+        }
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "postcss": {
+      "version": "7.0.14",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz",
+      "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.4.2",
+        "source-map": "^0.6.1",
+        "supports-color": "^6.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "5.5.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+              "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+              "dev": true,
+              "requires": {
+                "has-flag": "^3.0.0"
+              }
+            }
+          }
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "postcss-import": {
+      "version": "12.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
+      "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
+      "dev": true,
+      "requires": {
+        "postcss": "^7.0.1",
+        "postcss-value-parser": "^3.2.3",
+        "read-cache": "^1.0.0",
+        "resolve": "^1.1.7"
+      }
+    },
+    "postcss-load-config": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.0.0.tgz",
+      "integrity": "sha512-V5JBLzw406BB8UIfsAWSK2KSwIJ5yoEIVFb4gVkXci0QdKgA24jLmHZ/ghe/GgX0lJ0/D1uUK1ejhzEY94MChQ==",
+      "dev": true,
+      "requires": {
+        "cosmiconfig": "^4.0.0",
+        "import-cwd": "^2.0.0"
+      }
+    },
+    "postcss-loader": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+      "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "postcss": "^7.0.0",
+        "postcss-load-config": "^2.0.0",
+        "schema-utils": "^1.0.0"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+      "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+      "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+      "dev": true
+    },
+    "process": {
+      "version": "0.11.10",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+      "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "asap": "~2.0.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
+    },
+    "promise-polyfill": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
+      "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc="
+    },
+    "promise-retry": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz",
+      "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=",
+      "dev": true,
+      "requires": {
+        "err-code": "^1.0.0",
+        "retry": "^0.10.0"
+      }
+    },
+    "protoduck": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz",
+      "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==",
+      "dev": true,
+      "requires": {
+        "genfun": "^5.0.0"
+      }
+    },
+    "protractor": {
+      "version": "5.4.2",
+      "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.4.2.tgz",
+      "integrity": "sha512-zlIj64Cr6IOWP7RwxVeD8O4UskLYPoyIcg0HboWJL9T79F1F0VWtKkGTr/9GN6BKL+/Q/GmM7C9kFVCfDbP5sA==",
+      "dev": true,
+      "requires": {
+        "@types/q": "^0.0.32",
+        "@types/selenium-webdriver": "^3.0.0",
+        "blocking-proxy": "^1.0.0",
+        "browserstack": "^1.5.1",
+        "chalk": "^1.1.3",
+        "glob": "^7.0.3",
+        "jasmine": "2.8.0",
+        "jasminewd2": "^2.1.0",
+        "optimist": "~0.6.0",
+        "q": "1.4.1",
+        "saucelabs": "^1.5.0",
+        "selenium-webdriver": "3.6.0",
+        "source-map-support": "~0.4.0",
+        "webdriver-js-extender": "2.1.0",
+        "webdriver-manager": "^12.0.6"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        },
+        "source-map-support": {
+          "version": "0.4.18",
+          "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+          "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+          "dev": true,
+          "requires": {
+            "source-map": "^0.5.6"
+          }
+        }
+      }
+    },
+    "proxy-addr": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+      "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+      "dev": true,
+      "requires": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.9.0"
+      }
+    },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY="
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+      "dev": true
+    },
+    "psl": {
+      "version": "1.1.32",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz",
+      "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "pump": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      },
+      "dependencies": {
+        "pump": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+          "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+          "dev": true,
+          "requires": {
+            "end-of-stream": "^1.1.0",
+            "once": "^1.3.1"
+          }
+        }
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+      "dev": true
+    },
+    "q": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
+      "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
+      "dev": true
+    },
+    "qjobs": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+      "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+      "dev": true
+    },
+    "query-string": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+      "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+      "dev": true,
+      "requires": {
+        "decode-uri-component": "^0.2.0",
+        "object-assign": "^4.1.0",
+        "strict-uri-encode": "^1.0.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "querystring-es3": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+      "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+      "dev": true
+    },
+    "querystringify": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+      "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
+      "dev": true
+    },
+    "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"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+      "dev": true
+    },
+    "raw-body": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+      "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+      "dev": true,
+      "requires": {
+        "bytes": "3.1.0",
+        "http-errors": "1.7.2",
+        "iconv-lite": "0.4.24",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "bytes": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+          "dev": true
+        },
+        "http-errors": {
+          "version": "1.7.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+          "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+          "dev": true,
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.1",
+            "statuses": ">= 1.5.0 < 2",
+            "toidentifier": "1.0.0"
+          }
+        },
+        "setprototypeof": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+          "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+          "dev": true
+        }
+      }
+    },
+    "raw-loader": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz",
+      "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^1.0.0"
+      }
+    },
+    "read-cache": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+      "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+      "dev": true,
+      "requires": {
+        "pify": "^2.3.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "read-package-json": {
+      "version": "2.0.13",
+      "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz",
+      "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.1",
+        "graceful-fs": "^4.1.2",
+        "json-parse-better-errors": "^1.0.1",
+        "normalize-package-data": "^2.0.0",
+        "slash": "^1.0.0"
+      }
+    },
+    "read-package-tree": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.2.2.tgz",
+      "integrity": "sha512-rW3XWUUkhdKmN2JKB4FL563YAgtINifso5KShykufR03nJ5loGFlkUMe1g/yxmqX073SoYYTsgXu7XdDinKZuA==",
+      "dev": true,
+      "requires": {
+        "debuglog": "^1.0.1",
+        "dezalgo": "^1.0.0",
+        "once": "^1.3.0",
+        "read-package-json": "^2.0.0",
+        "readdir-scoped-modules": "^1.0.0"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+      "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "readdir-scoped-modules": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz",
+      "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=",
+      "dev": true,
+      "requires": {
+        "debuglog": "^1.0.1",
+        "dezalgo": "^1.0.0",
+        "graceful-fs": "^4.1.2",
+        "once": "^1.3.0"
+      }
+    },
+    "readdirp": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+      "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "micromatch": "^3.1.10",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.1.6"
+      }
+    },
+    "reflect-metadata": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
+      "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==",
+      "dev": true
+    },
+    "regenerate": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+      "dev": true
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+      "dev": true
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "regexpu-core": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+      "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+      "dev": true,
+      "requires": {
+        "regenerate": "^1.2.1",
+        "regjsgen": "^0.2.0",
+        "regjsparser": "^0.1.4"
+      }
+    },
+    "regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+      "dev": true,
+      "requires": {
+        "jsesc": "~0.5.0"
+      },
+      "dependencies": {
+        "jsesc": {
+          "version": "0.5.0",
+          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+          "dev": true
+        }
+      }
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "dev": true,
+      "requires": {
+        "is-finite": "^1.0.0"
+      }
+    },
+    "request": {
+      "version": "2.88.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+      "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+      "dev": true,
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.0",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.4.3",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+    },
+    "require-from-string": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+      "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+    },
+    "requirejs": {
+      "version": "2.3.6",
+      "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.6.tgz",
+      "integrity": "sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg=="
+    },
+    "requires-port": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+      "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+      "dev": true
+    },
+    "resolve": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+      "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
+      "dev": true,
+      "requires": {
+        "path-parse": "^1.0.6"
+      }
+    },
+    "resolve-cwd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+      "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+      "dev": true,
+      "requires": {
+        "resolve-from": "^3.0.0"
+      }
+    },
+    "resolve-from": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+      "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "^2.0.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "retry": {
+      "version": "0.10.1",
+      "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
+      "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
+      "dev": true
+    },
+    "rfdc": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.4.tgz",
+      "integrity": "sha512-5C9HXdzK8EAqN7JDif30jqsBzavB7wLpaubisuQIGHWf2gUXSpzy6ArX/+Da8RjFpagWsCn+pIgxTMAmKw9Zug==",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.6.3",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+      "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.1.3"
+      }
+    },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "^2.1.0"
+      }
+    },
+    "run-queue": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+      "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+      "dev": true,
+      "requires": {
+        "aproba": "^1.1.1"
+      }
+    },
+    "rxjs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
+      "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
+      "requires": {
+        "tslib": "^1.9.0"
+      }
+    },
+    "rxjs-compat": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.5.2.tgz",
+      "integrity": "sha512-TRMkTp4FgSxE2HtGvxmgRukh3JqdFM7ejAj1Ti/VdodbPGfWvZR5+KdLKRV9jVDFyu2SknM8RD+PR54KGnoLjg=="
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+      "dev": true
+    },
+    "sass": {
+      "version": "1.19.0",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.19.0.tgz",
+      "integrity": "sha512-8kzKCgxCzh8/zEn3AuRwzLWVSSFj8omkiGwqdJdeOufjM+I88dXxu9LYJ/Gw4rRTHXesN0r1AixBuqM6yLQUJw==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^2.0.0"
+      }
+    },
+    "sass-loader": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz",
+      "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==",
+      "dev": true,
+      "requires": {
+        "clone-deep": "^2.0.1",
+        "loader-utils": "^1.0.1",
+        "lodash.tail": "^4.1.1",
+        "neo-async": "^2.5.0",
+        "pify": "^3.0.0",
+        "semver": "^5.5.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "saucelabs": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz",
+      "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==",
+      "dev": true,
+      "requires": {
+        "https-proxy-agent": "^2.2.1"
+      }
+    },
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+      "dev": true
+    },
+    "schema-utils": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+      "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+      "dev": true,
+      "requires": {
+        "ajv": "^6.1.0",
+        "ajv-errors": "^1.0.0",
+        "ajv-keywords": "^3.1.0"
+      }
+    },
+    "screenfull": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/screenfull/-/screenfull-4.2.0.tgz",
+      "integrity": "sha512-qpyI9XbwuMJElWRP5vTgxkFAl4k7HpyhIqBFOZEwX9QBXn0MAuRSpn7LOc6/4CeSwoz61oBu1VPV+2fbIWC+5Q=="
+    },
+    "select-hose": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+      "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+      "dev": true
+    },
+    "selenium-webdriver": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
+      "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==",
+      "dev": true,
+      "requires": {
+        "jszip": "^3.1.3",
+        "rimraf": "^2.5.4",
+        "tmp": "0.0.30",
+        "xml2js": "^0.4.17"
+      },
+      "dependencies": {
+        "tmp": {
+          "version": "0.0.30",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
+          "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
+          "dev": true,
+          "requires": {
+            "os-tmpdir": "~1.0.1"
+          }
+        }
+      }
+    },
+    "selfsigned": {
+      "version": "1.10.4",
+      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz",
+      "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==",
+      "dev": true,
+      "requires": {
+        "node-forge": "0.7.5"
+      }
+    },
+    "semver": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+      "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
+    },
+    "semver-dsl": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
+      "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=",
+      "dev": true,
+      "requires": {
+        "semver": "^5.3.0"
+      }
+    },
+    "semver-intersect": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz",
+      "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==",
+      "dev": true,
+      "requires": {
+        "semver": "^5.0.0"
+      }
+    },
+    "send": {
+      "version": "0.17.1",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+      "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.7.2",
+        "mime": "1.6.0",
+        "ms": "2.1.1",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.1",
+        "statuses": "~1.5.0"
+      },
+      "dependencies": {
+        "http-errors": {
+          "version": "1.7.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+          "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+          "dev": true,
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.1",
+            "statuses": ">= 1.5.0 < 2",
+            "toidentifier": "1.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+          "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+          "dev": true
+        },
+        "range-parser": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+          "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+          "dev": true
+        },
+        "setprototypeof": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+          "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+          "dev": true
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+          "dev": true
+        }
+      }
+    },
+    "serialize-javascript": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz",
+      "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==",
+      "dev": true
+    },
+    "serve-index": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+      "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+      "dev": true,
+      "requires": {
+        "accepts": "~1.3.4",
+        "batch": "0.6.1",
+        "debug": "2.6.9",
+        "escape-html": "~1.0.3",
+        "http-errors": "~1.6.2",
+        "mime-types": "~2.1.17",
+        "parseurl": "~1.3.2"
+      }
+    },
+    "serve-static": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+      "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+      "dev": true,
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.3",
+        "send": "0.17.1"
+      },
+      "dependencies": {
+        "parseurl": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+          "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+          "dev": true
+        }
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+    },
+    "set-immediate-shim": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+      "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+      "dev": true
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+      "dev": true
+    },
+    "setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+      "dev": true
+    },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://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"
+      }
+    },
+    "shallow-clone": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
+      "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
+      "dev": true,
+      "requires": {
+        "is-extendable": "^0.1.1",
+        "kind-of": "^5.0.0",
+        "mixin-object": "^2.0.1"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
+    },
+    "shelljs": {
+      "version": "0.8.3",
+      "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
+      "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==",
+      "dev": true,
+      "requires": {
+        "glob": "^7.0.0",
+        "interpret": "^1.0.0",
+        "rechoir": "^0.6.2"
+      }
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+    },
+    "simple-line-icons": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/simple-line-icons/-/simple-line-icons-2.4.1.tgz",
+      "integrity": "sha1-t1vFoNh+UwkowszaVzUnS7JW8jQ="
+    },
+    "slash": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+      "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+      "dev": true
+    },
+    "smart-buffer": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz",
+      "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==",
+      "dev": true
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "socket.io": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz",
+      "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==",
+      "dev": true,
+      "requires": {
+        "debug": "~3.1.0",
+        "engine.io": "~3.2.0",
+        "has-binary2": "~1.0.2",
+        "socket.io-adapter": "~1.1.0",
+        "socket.io-client": "2.1.1",
+        "socket.io-parser": "~3.2.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "socket.io-adapter": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
+      "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==",
+      "dev": true
+    },
+    "socket.io-client": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz",
+      "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==",
+      "dev": true,
+      "requires": {
+        "backo2": "1.0.2",
+        "base64-arraybuffer": "0.1.5",
+        "component-bind": "1.0.0",
+        "component-emitter": "1.2.1",
+        "debug": "~3.1.0",
+        "engine.io-client": "~3.2.0",
+        "has-binary2": "~1.0.2",
+        "has-cors": "1.1.0",
+        "indexof": "0.0.1",
+        "object-component": "0.0.3",
+        "parseqs": "0.0.5",
+        "parseuri": "0.0.5",
+        "socket.io-parser": "~3.2.0",
+        "to-array": "0.1.4"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
+    "socket.io-parser": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
+      "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==",
+      "dev": true,
+      "requires": {
+        "component-emitter": "1.2.1",
+        "debug": "~3.1.0",
+        "isarray": "2.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "isarray": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=",
+          "dev": true
+        }
+      }
+    },
+    "sockjs": {
+      "version": "0.3.19",
+      "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+      "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+      "dev": true,
+      "requires": {
+        "faye-websocket": "^0.10.0",
+        "uuid": "^3.0.1"
+      }
+    },
+    "sockjs-client": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz",
+      "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==",
+      "dev": true,
+      "requires": {
+        "debug": "^3.2.5",
+        "eventsource": "^1.0.7",
+        "faye-websocket": "~0.11.1",
+        "inherits": "^2.0.3",
+        "json3": "^3.3.2",
+        "url-parse": "^1.4.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "faye-websocket": {
+          "version": "0.11.3",
+          "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
+          "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
+          "dev": true,
+          "requires": {
+            "websocket-driver": ">=0.5.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "socks": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.2.tgz",
+      "integrity": "sha512-pCpjxQgOByDHLlNqlnh/mNSAxIUkyBBuwwhTcV+enZGbDaClPvHdvm6uvOwZfFJkam7cGhBNbb4JxiP8UZkRvQ==",
+      "dev": true,
+      "requires": {
+        "ip": "^1.1.5",
+        "smart-buffer": "4.0.2"
+      }
+    },
+    "socks-proxy-agent": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz",
+      "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==",
+      "dev": true,
+      "requires": {
+        "agent-base": "~4.2.1",
+        "socks": "~2.3.2"
+      },
+      "dependencies": {
+        "agent-base": {
+          "version": "4.2.1",
+          "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+          "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+          "dev": true,
+          "requires": {
+            "es6-promisify": "^5.0.0"
+          }
+        }
+      }
+    },
+    "sort-keys": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+      "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+      "dev": true,
+      "requires": {
+        "is-plain-obj": "^1.0.0"
+      }
+    },
+    "source-list-map": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+      "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+      "dev": true
+    },
+    "source-map": {
+      "version": "0.7.3",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+      "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+      "dev": true
+    },
+    "source-map-loader": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz",
+      "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==",
+      "dev": true,
+      "requires": {
+        "async": "^2.5.0",
+        "loader-utils": "^1.1.0"
+      }
+    },
+    "source-map-resolve": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.1",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-support": {
+      "version": "0.5.12",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
+      "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "source-map": "^0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "source-sans-pro": {
+      "version": "2.45.0",
+      "resolved": "https://registry.npmjs.org/source-sans-pro/-/source-sans-pro-2.45.0.tgz",
+      "integrity": "sha512-MBbmgyzlD0yCKAvJ4Q86s9BB8yXYld26joJh0DMD53j9aFJZYnFo/B7f4RKXDUfX9I4FyEfdr51lOaVioAOBHw=="
+    },
+    "sourcemap-codec": {
+      "version": "1.4.4",
+      "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.4.tgz",
+      "integrity": "sha512-CYAPYdBu34781kLHkaW3m6b/uUSyMOC2R61gcYMWooeuaGtjof86ZA/8T+qVPPt7np1085CR9hmMGrySwEc8Xg==",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+      "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+      "dev": true,
+      "requires": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
+      "dev": true
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+      "dev": true,
+      "requires": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
+      "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==",
+      "dev": true
+    },
+    "spdy": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz",
+      "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "handle-thing": "^2.0.0",
+        "http-deceiver": "^1.2.7",
+        "select-hose": "^2.0.0",
+        "spdy-transport": "^3.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "spdy-transport": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+      "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+      "dev": true,
+      "requires": {
+        "debug": "^4.1.0",
+        "detect-node": "^2.0.4",
+        "hpack.js": "^2.1.6",
+        "obuf": "^1.1.2",
+        "readable-stream": "^3.0.6",
+        "wbuf": "^1.7.3"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "3.4.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
+          "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
+    "speed-measure-webpack-plugin": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz",
+      "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==",
+      "dev": true,
+      "requires": {
+        "chalk": "^2.0.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+    },
+    "sshpk": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+      "dev": true,
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      }
+    },
+    "ssri": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+      "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1"
+      }
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "stats-webpack-plugin": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/stats-webpack-plugin/-/stats-webpack-plugin-0.7.0.tgz",
+      "integrity": "sha512-NT0YGhwuQ0EOX+uPhhUcI6/+1Sq/pMzNuSCBVT4GbFl/ac6I/JZefBcjlECNfAb1t3GOx5dEj1Z7x0cAxeeVLQ==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.4"
+      }
+    },
+    "statuses": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+      "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+      "dev": true
+    },
+    "stream-browserify": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+      "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+      "dev": true,
+      "requires": {
+        "inherits": "~2.0.1",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "stream-each": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+      "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "stream-http": {
+      "version": "2.8.3",
+      "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+      "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+      "dev": true,
+      "requires": {
+        "builtin-status-codes": "^3.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.3.6",
+        "to-arraybuffer": "^1.0.0",
+        "xtend": "^4.0.0"
+      }
+    },
+    "stream-shift": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+      "dev": true
+    },
+    "streamroller": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-1.0.6.tgz",
+      "integrity": "sha512-3QC47Mhv3/aZNFpDDVO44qQb9gwB9QggMEE0sQmkTAwBVYdBRWISdsywlkfm5II1Q5y/pmrHflti/IgmIzdDBg==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.2",
+        "date-format": "^2.0.0",
+        "debug": "^3.2.6",
+        "fs-extra": "^7.0.1",
+        "lodash": "^4.17.14"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "lodash": {
+          "version": "4.17.15",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+          "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+      "dev": true
+    },
+    "string-width": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+      "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+      "requires": {
+        "emoji-regex": "^7.0.1",
+        "is-fullwidth-code-point": "^2.0.0",
+        "strip-ansi": "^5.1.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "dev": true,
+      "requires": {
+        "is-utf8": "^0.2.0"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
+    },
+    "style-loader": {
+      "version": "0.23.1",
+      "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz",
+      "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0",
+        "schema-utils": "^1.0.0"
+      }
+    },
+    "stylus": {
+      "version": "0.54.5",
+      "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz",
+      "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=",
+      "dev": true,
+      "requires": {
+        "css-parse": "1.7.x",
+        "debug": "*",
+        "glob": "7.0.x",
+        "mkdirp": "0.5.x",
+        "sax": "0.5.x",
+        "source-map": "0.1.x"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "7.0.6",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+          "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.2",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "sax": {
+          "version": "0.5.8",
+          "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
+          "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.1.43",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "dev": true,
+          "requires": {
+            "amdefine": ">=0.0.4"
+          }
+        }
+      }
+    },
+    "stylus-loader": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz",
+      "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.0.2",
+        "lodash.clonedeep": "^4.5.0",
+        "when": "~3.6.x"
+      }
+    },
+    "summernote": {
+      "version": "0.8.12",
+      "resolved": "https://registry.npmjs.org/summernote/-/summernote-0.8.12.tgz",
+      "integrity": "sha512-RVEJoIyztwPpopTwZvjag1WOvbmhUGFe6Mc9RADzzcX1ogG8pIXCB88icu/vjNYihITrzj2zZsoFMcDRHSlhEA=="
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+      "dev": true
+    },
+    "sweetalert": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/sweetalert/-/sweetalert-2.1.2.tgz",
+      "integrity": "sha512-iWx7X4anRBNDa/a+AdTmvAzQtkN1+s4j/JJRWlHpYE8Qimkohs8/XnFcWeYHH2lMA8LRCa5tj2d244If3S/hzA==",
+      "requires": {
+        "es6-object-assign": "^1.1.0",
+        "promise-polyfill": "^6.0.2"
+      }
+    },
+    "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==",
+      "dev": true
+    },
+    "tapable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+      "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
+    },
+    "tar": {
+      "version": "4.4.10",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
+      "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
+      "dev": true,
+      "requires": {
+        "chownr": "^1.1.1",
+        "fs-minipass": "^1.2.5",
+        "minipass": "^2.3.5",
+        "minizlib": "^1.2.1",
+        "mkdirp": "^0.5.0",
+        "safe-buffer": "^5.1.2",
+        "yallist": "^3.0.3"
+      }
+    },
+    "terser": {
+      "version": "3.17.0",
+      "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
+      "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
+      "dev": true,
+      "requires": {
+        "commander": "^2.19.0",
+        "source-map": "~0.6.1",
+        "source-map-support": "~0.5.10"
+      },
+      "dependencies": {
+        "commander": {
+          "version": "2.20.0",
+          "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
+          "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "terser-webpack-plugin": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz",
+      "integrity": "sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA==",
+      "dev": true,
+      "requires": {
+        "cacache": "^11.0.2",
+        "find-cache-dir": "^2.0.0",
+        "schema-utils": "^1.0.0",
+        "serialize-javascript": "^1.4.0",
+        "source-map": "^0.6.1",
+        "terser": "^3.16.1",
+        "webpack-sources": "^1.1.0",
+        "worker-farm": "^1.5.2"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
+        }
+      }
+    },
+    "text-mask-core": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/text-mask-core/-/text-mask-core-5.1.2.tgz",
+      "integrity": "sha1-gN1evgSCV1fkZhnmkUB6n4s8G28="
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.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"
+      }
+    },
+    "thunky": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz",
+      "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==",
+      "dev": true
+    },
+    "timers-browserify": {
+      "version": "2.0.10",
+      "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
+      "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
+      "dev": true,
+      "requires": {
+        "setimmediate": "^1.0.4"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
+      "requires": {
+        "os-tmpdir": "~1.0.2"
+      }
+    },
+    "to-array": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+      "dev": true
+    },
+    "to-arraybuffer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+      "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+      "dev": true
+    },
+    "to-fast-properties": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+      "dev": true
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "3.2.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+          "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+      "dev": true
+    },
+    "tough-cookie": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+      "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+      "dev": true,
+      "requires": {
+        "psl": "^1.1.24",
+        "punycode": "^1.4.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+          "dev": true
+        }
+      }
+    },
+    "tree-kill": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.1.tgz",
+      "integrity": "sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==",
+      "dev": true
+    },
+    "trim-right": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+      "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+      "dev": true
+    },
+    "ts-helpers": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/ts-helpers/-/ts-helpers-1.1.2.tgz",
+      "integrity": "sha1-/Gm+nx87rtAfsaDvjUz+dIgU2DU="
+    },
+    "ts-node": {
+      "version": "8.2.0",
+      "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.2.0.tgz",
+      "integrity": "sha512-m8XQwUurkbYqXrKqr3WHCW310utRNvV5OnRVeISeea7LoCWVcdfeB/Ntl8JYWFh+WRoUAdBgESrzKochQt7sMw==",
+      "dev": true,
+      "requires": {
+        "arg": "^4.1.0",
+        "diff": "^4.0.1",
+        "make-error": "^1.1.1",
+        "source-map-support": "^0.5.6",
+        "yn": "^3.0.0"
+      }
+    },
+    "tslib": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+      "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
+    },
+    "tslint": {
+      "version": "5.17.0",
+      "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz",
+      "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==",
+      "dev": true,
+      "requires": {
+        "@babel/code-frame": "^7.0.0",
+        "builtin-modules": "^1.1.1",
+        "chalk": "^2.3.0",
+        "commander": "^2.12.1",
+        "diff": "^3.2.0",
+        "glob": "^7.1.1",
+        "js-yaml": "^3.13.1",
+        "minimatch": "^3.0.4",
+        "mkdirp": "^0.5.1",
+        "resolve": "^1.3.2",
+        "semver": "^5.3.0",
+        "tslib": "^1.8.0",
+        "tsutils": "^2.29.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "diff": {
+          "version": "3.5.0",
+          "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+          "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+          "dev": true
+        },
+        "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"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "tsutils": {
+      "version": "2.29.0",
+      "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+      "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+      "dev": true,
+      "requires": {
+        "tslib": "^1.8.1"
+      }
+    },
+    "tty-browserify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+      "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+      "dev": true
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "dev": true
+    },
+    "type-is": {
+      "version": "1.6.18",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+      "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+      "dev": true,
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.24"
+      },
+      "dependencies": {
+        "mime-db": {
+          "version": "1.42.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz",
+          "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==",
+          "dev": true
+        },
+        "mime-types": {
+          "version": "2.1.25",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz",
+          "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==",
+          "dev": true,
+          "requires": {
+            "mime-db": "1.42.0"
+          }
+        }
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "typescript": {
+      "version": "3.4.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz",
+      "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==",
+      "dev": true
+    },
+    "uc.micro": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+      "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+    },
+    "uglify-js": {
+      "version": "3.4.9",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+      "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "commander": "~2.17.1",
+        "source-map": "~0.6.1"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
+          "optional": true
+        }
+      }
+    },
+    "ultron": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+      "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-extendable": "^0.1.1",
+            "is-plain-object": "^2.0.1",
+            "to-object-path": "^0.3.0"
+          }
+        }
+      }
+    },
+    "unique-filename": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+      "dev": true,
+      "requires": {
+        "unique-slug": "^2.0.0"
+      }
+    },
+    "unique-slug": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz",
+      "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==",
+      "dev": true,
+      "requires": {
+        "imurmurhash": "^0.1.4"
+      }
+    },
+    "universal-analytics": {
+      "version": "0.4.20",
+      "resolved": "https://registry.npmjs.org/universal-analytics/-/universal-analytics-0.4.20.tgz",
+      "integrity": "sha512-gE91dtMvNkjO+kWsPstHRtSwHXz0l2axqptGYp5ceg4MsuurloM0PU3pdOfpb5zBXUvyjT4PwhWK2m39uczZuw==",
+      "dev": true,
+      "requires": {
+        "debug": "^3.0.0",
+        "request": "^2.88.0",
+        "uuid": "^3.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        }
+      }
+    },
+    "universalify": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+      "dev": true
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+      "dev": true
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        }
+      }
+    },
+    "upath": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
+      "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+      "dev": true
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "dev": true,
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
+      "requires": {
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
+        }
+      }
+    },
+    "url-parse": {
+      "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"
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "useragent": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+      "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+      "dev": true,
+      "requires": {
+        "lru-cache": "4.1.x",
+        "tmp": "0.0.x"
+      },
+      "dependencies": {
+        "lru-cache": {
+          "version": "4.1.5",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+          "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+          "dev": true,
+          "requires": {
+            "pseudomap": "^1.0.2",
+            "yallist": "^2.1.2"
+          }
+        },
+        "yallist": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+          "dev": true
+        }
+      }
+    },
+    "util": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+      "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+      "dev": true
+    },
+    "uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+      "dev": true
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "dev": true,
+      "requires": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "validate-npm-package-name": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz",
+      "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=",
+      "dev": true,
+      "requires": {
+        "builtins": "^1.0.3"
+      }
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "dev": true,
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "viewerjs": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.5.0.tgz",
+      "integrity": "sha512-ZiJ0vrXDvomLSY3ixaZCJtmdenomsvPPQwZKwvtXUMCiO2HHtFGoB/KqpS9QzABSeKaRLfcENp1uRYJ7l1MkYQ=="
+    },
+    "vm-browserify": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+      "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+      "dev": true,
+      "requires": {
+        "indexof": "0.0.1"
+      }
+    },
+    "void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+      "dev": true
+    },
+    "watchpack": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
+      "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^2.0.2",
+        "graceful-fs": "^4.1.2",
+        "neo-async": "^2.5.0"
+      }
+    },
+    "wbuf": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+      "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+      "dev": true,
+      "requires": {
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
+    "web-animations-js": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/web-animations-js/-/web-animations-js-2.3.1.tgz",
+      "integrity": "sha1-Om2bwVGWN3qQ+OKAP6UmIWWwRRA="
+    },
+    "webdriver-js-extender": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz",
+      "integrity": "sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==",
+      "dev": true,
+      "requires": {
+        "@types/selenium-webdriver": "^3.0.0",
+        "selenium-webdriver": "^3.0.1"
+      }
+    },
+    "webdriver-manager": {
+      "version": "12.1.5",
+      "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.1.5.tgz",
+      "integrity": "sha512-f1apDjMpZ8SHlXtXGzqBxOjV+WQcDRz5PN7pWScgjXS7vhUIFcM3V89Shetf4A04n8DDR2MxiVQq6JproFcRZw==",
+      "dev": true,
+      "requires": {
+        "adm-zip": "^0.4.9",
+        "chalk": "^1.1.1",
+        "del": "^2.2.0",
+        "glob": "^7.0.3",
+        "ini": "^1.3.4",
+        "minimist": "^1.2.0",
+        "q": "^1.4.1",
+        "request": "^2.87.0",
+        "rimraf": "^2.5.2",
+        "semver": "^5.3.0",
+        "xml2js": "^0.4.17"
+      },
+      "dependencies": {
+        "del": {
+          "version": "2.2.2",
+          "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+          "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+          "dev": true,
+          "requires": {
+            "globby": "^5.0.0",
+            "is-path-cwd": "^1.0.0",
+            "is-path-in-cwd": "^1.0.0",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0",
+            "rimraf": "^2.2.8"
+          }
+        },
+        "globby": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+          "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+          "dev": true,
+          "requires": {
+            "array-union": "^1.0.1",
+            "arrify": "^1.0.0",
+            "glob": "^7.0.3",
+            "object-assign": "^4.0.1",
+            "pify": "^2.0.0",
+            "pinkie-promise": "^2.0.0"
+          }
+        },
+        "is-path-cwd": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+          "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+          "dev": true
+        },
+        "is-path-in-cwd": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+          "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
+          "dev": true,
+          "requires": {
+            "is-path-inside": "^1.0.0"
+          }
+        },
+        "is-path-inside": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+          "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+          "dev": true,
+          "requires": {
+            "path-is-inside": "^1.0.1"
+          }
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "pify": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+          "dev": true
+        }
+      }
+    },
+    "webpack": {
+      "version": "4.30.0",
+      "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.30.0.tgz",
+      "integrity": "sha512-4hgvO2YbAFUhyTdlR4FNyt2+YaYBYHavyzjCMbZzgglo02rlKi/pcsEzwCuCpsn1ryzIl1cq/u8ArIKu8JBYMg==",
+      "dev": true,
+      "requires": {
+        "@webassemblyjs/ast": "1.8.5",
+        "@webassemblyjs/helper-module-context": "1.8.5",
+        "@webassemblyjs/wasm-edit": "1.8.5",
+        "@webassemblyjs/wasm-parser": "1.8.5",
+        "acorn": "^6.0.5",
+        "acorn-dynamic-import": "^4.0.0",
+        "ajv": "^6.1.0",
+        "ajv-keywords": "^3.1.0",
+        "chrome-trace-event": "^1.0.0",
+        "enhanced-resolve": "^4.1.0",
+        "eslint-scope": "^4.0.0",
+        "json-parse-better-errors": "^1.0.2",
+        "loader-runner": "^2.3.0",
+        "loader-utils": "^1.1.0",
+        "memory-fs": "~0.4.1",
+        "micromatch": "^3.1.8",
+        "mkdirp": "~0.5.0",
+        "neo-async": "^2.5.0",
+        "node-libs-browser": "^2.0.0",
+        "schema-utils": "^1.0.0",
+        "tapable": "^1.1.0",
+        "terser-webpack-plugin": "^1.1.0",
+        "watchpack": "^1.5.0",
+        "webpack-sources": "^1.3.0"
+      }
+    },
+    "webpack-core": {
+      "version": "0.6.9",
+      "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz",
+      "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=",
+      "dev": true,
+      "requires": {
+        "source-list-map": "~0.1.7",
+        "source-map": "~0.4.1"
+      },
+      "dependencies": {
+        "source-list-map": {
+          "version": "0.1.8",
+          "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz",
+          "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+          "dev": true,
+          "requires": {
+            "amdefine": ">=0.0.4"
+          }
+        }
+      }
+    },
+    "webpack-dev-middleware": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.6.2.tgz",
+      "integrity": "sha512-A47I5SX60IkHrMmZUlB0ZKSWi29TZTcPz7cha1Z75yYOsgWh/1AcPmQEbC8ZIbU3A1ytSv1PMU0PyPz2Lmz2jg==",
+      "dev": true,
+      "requires": {
+        "memory-fs": "^0.4.1",
+        "mime": "^2.3.1",
+        "range-parser": "^1.0.3",
+        "webpack-log": "^2.0.0"
+      },
+      "dependencies": {
+        "mime": {
+          "version": "2.4.4",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
+          "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-dev-server": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.3.1.tgz",
+      "integrity": "sha512-jY09LikOyGZrxVTXK0mgIq9y2IhCoJ05848dKZqX1gAGLU1YDqgpOT71+W53JH/wI4v6ky4hm+KvSyW14JEs5A==",
+      "dev": true,
+      "requires": {
+        "ansi-html": "0.0.7",
+        "bonjour": "^3.5.0",
+        "chokidar": "^2.1.5",
+        "compression": "^1.7.4",
+        "connect-history-api-fallback": "^1.6.0",
+        "debug": "^4.1.1",
+        "del": "^4.1.0",
+        "express": "^4.16.4",
+        "html-entities": "^1.2.1",
+        "http-proxy-middleware": "^0.19.1",
+        "import-local": "^2.0.0",
+        "internal-ip": "^4.2.0",
+        "ip": "^1.1.5",
+        "killable": "^1.0.1",
+        "loglevel": "^1.6.1",
+        "opn": "^5.5.0",
+        "portfinder": "^1.0.20",
+        "schema-utils": "^1.0.0",
+        "selfsigned": "^1.10.4",
+        "semver": "^6.0.0",
+        "serve-index": "^1.9.1",
+        "sockjs": "0.3.19",
+        "sockjs-client": "1.3.0",
+        "spdy": "^4.0.0",
+        "strip-ansi": "^3.0.1",
+        "supports-color": "^6.1.0",
+        "url": "^0.11.0",
+        "webpack-dev-middleware": "^3.6.2",
+        "webpack-log": "^2.0.0",
+        "yargs": "12.0.5"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "chokidar": {
+          "version": "2.1.6",
+          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
+          "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
+          "dev": true,
+          "requires": {
+            "anymatch": "^2.0.0",
+            "async-each": "^1.0.1",
+            "braces": "^2.3.2",
+            "fsevents": "^1.2.7",
+            "glob-parent": "^3.1.0",
+            "inherits": "^2.0.3",
+            "is-binary-path": "^1.0.0",
+            "is-glob": "^4.0.0",
+            "normalize-path": "^3.0.0",
+            "path-is-absolute": "^1.0.0",
+            "readdirp": "^2.2.1",
+            "upath": "^1.1.1"
+          }
+        },
+        "cliui": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^2.1.1",
+            "strip-ansi": "^4.0.0",
+            "wrap-ansi": "^2.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "get-caller-file": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+          "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "normalize-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+          "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+          "dev": true
+        },
+        "require-main-filename": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+          "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+          "dev": true
+        },
+        "semver": {
+          "version": "6.1.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz",
+          "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          },
+          "dependencies": {
+            "strip-ansi": {
+              "version": "4.0.0",
+              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+              "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+              "dev": true,
+              "requires": {
+                "ansi-regex": "^3.0.0"
+              }
+            }
+          }
+        },
+        "supports-color": {
+          "version": "6.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+          "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "upath": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
+          "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+          "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+          "dev": true,
+          "requires": {
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1"
+          },
+          "dependencies": {
+            "is-fullwidth-code-point": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+              "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+              "dev": true,
+              "requires": {
+                "number-is-nan": "^1.0.0"
+              }
+            },
+            "string-width": {
+              "version": "1.0.2",
+              "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+              "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+              "dev": true,
+              "requires": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+              }
+            }
+          }
+        },
+        "yargs": {
+          "version": "12.0.5",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
+          "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
+          "dev": true,
+          "requires": {
+            "cliui": "^4.0.0",
+            "decamelize": "^1.2.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^1.0.1",
+            "os-locale": "^3.0.0",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^1.0.1",
+            "set-blocking": "^2.0.0",
+            "string-width": "^2.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^3.2.1 || ^4.0.0",
+            "yargs-parser": "^11.1.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "11.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
+          "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
+    "webpack-log": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+      "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+      "dev": true,
+      "requires": {
+        "ansi-colors": "^3.0.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "webpack-merge": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.1.tgz",
+      "integrity": "sha512-4p8WQyS98bUJcCvFMbdGZyZmsKuWjWVnVHnAS3FFg0HDaRVrPbkivx2RYCre8UiemD67RsiFFLfn4JhLAin8Vw==",
+      "dev": true,
+      "requires": {
+        "lodash": "^4.17.5"
+      }
+    },
+    "webpack-sources": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz",
+      "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==",
+      "dev": true,
+      "requires": {
+        "source-list-map": "^2.0.0",
+        "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==",
+          "dev": true
+        }
+      }
+    },
+    "webpack-subresource-integrity": {
+      "version": "1.1.0-rc.6",
+      "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.1.0-rc.6.tgz",
+      "integrity": "sha512-Az7y8xTniNhaA0620AV1KPwWOqawurVVDzQSpPAeR5RwNbL91GoBSJAAo9cfd+GiFHwsS5bbHepBw1e6Hzxy4w==",
+      "dev": true,
+      "requires": {
+        "webpack-core": "^0.6.8"
+      }
+    },
+    "websocket-driver": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.1.tgz",
+      "integrity": "sha512-EC4YX5LEHtiB1XjaCh6++35jGaFmhT7687pySyCfPX9bB8Quw7+Fpx8gSCpkD78tPjalxuoOm8TtTz8K4dAQEg==",
+      "dev": true,
+      "requires": {
+        "http-parser-js": ">=0.4.0",
+        "safe-buffer": ">=5.1.1",
+        "websocket-extensions": ">=0.1.1"
+      }
+    },
+    "websocket-extensions": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+      "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+      "dev": true
+    },
+    "when": {
+      "version": "3.6.4",
+      "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz",
+      "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=",
+      "dev": true
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+      "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+    },
+    "worker-farm": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+      "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+      "dev": true,
+      "requires": {
+        "errno": "~0.1.7"
+      }
+    },
+    "worker-plugin": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/worker-plugin/-/worker-plugin-3.1.0.tgz",
+      "integrity": "sha512-iQ9KTTmmN5fhfc2KMR7CcDblvcrg1QQ4pXymqZ3cRZF8L0890YLBcEqlIsGPdxoFwghyN8RA1pCEhCKuTF4Lkw==",
+      "dev": true,
+      "requires": {
+        "loader-utils": "^1.1.0"
+      }
+    },
+    "wrap-ansi": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+      "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+      "requires": {
+        "ansi-styles": "^3.2.0",
+        "string-width": "^3.0.0",
+        "strip-ansi": "^5.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        }
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "ws": {
+      "version": "3.3.3",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+      "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+      "dev": true,
+      "requires": {
+        "async-limiter": "~1.0.0",
+        "safe-buffer": "~5.1.0",
+        "ultron": "~1.1.0"
+      }
+    },
+    "xml2js": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "dev": true,
+      "requires": {
+        "sax": ">=0.6.0",
+        "xmlbuilder": "~9.0.1"
+      }
+    },
+    "xmlbuilder": {
+      "version": "9.0.7",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+      "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
+      "dev": true
+    },
+    "xmlhttprequest-ssl": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+      "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
+      "dev": true
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "y18n": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+      "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
+    },
+    "yallist": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
+      "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
+      "dev": true
+    },
+    "yargs": {
+      "version": "13.2.4",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz",
+      "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
+      "requires": {
+        "cliui": "^5.0.0",
+        "find-up": "^3.0.0",
+        "get-caller-file": "^2.0.1",
+        "os-locale": "^3.1.0",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^2.0.0",
+        "set-blocking": "^2.0.0",
+        "string-width": "^3.0.0",
+        "which-module": "^2.0.0",
+        "y18n": "^4.0.0",
+        "yargs-parser": "^13.1.0"
+      }
+    },
+    "yargs-parser": {
+      "version": "13.1.1",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
+      "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+      "requires": {
+        "camelcase": "^5.0.0",
+        "decamelize": "^1.2.0"
+      }
+    },
+    "yeast": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+      "dev": true
+    },
+    "yn": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz",
+      "integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==",
+      "dev": true
+    },
+    "zone.js": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.9.1.tgz",
+      "integrity": "sha512-GkPiJL8jifSrKReKaTZ5jkhrMEgXbXYC+IPo1iquBjayRa0q86w3Dipjn8b415jpitMExe9lV8iTsv8tk3DGag=="
+    },
+    "zrender": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/zrender/-/zrender-4.2.0.tgz",
+      "integrity": "sha512-YJ9hxt5uFincYYU3KK31+Ce+B6PJmYYK0Q9fQ6jOUAoC/VHbe4kCKAPkxKeT7jGTxrK5wYu18R0TLGqj2zbEOA=="
+    }
+  }
+}

+ 96 - 0
package.json

@@ -0,0 +1,96 @@
+{
+  "name": "hm2soft",
+  "version": "2.0.0",
+  "description": "HeMu Soft Manage Platform",
+  "author": "@Zhang XiaoQing",
+  "license": "www.hmsoft.cn",
+  "private": true,
+  "scripts": {
+    "ng": "ng",
+    "start": "ng serve  --proxy-config proxy.conf.json",
+    "build": "ng build --prod",
+    "test": "ng test",
+    "lint": "ng lint",
+    "e2e": "ng e2e"
+  },
+  "dependencies": {
+    "@angular/animations": "8.0.0",
+    "@angular/common": "8.0.0",
+    "@angular/compiler": "8.0.0",
+    "@angular/core": "8.0.0",
+    "@angular/forms": "8.0.0",
+    "@angular/platform-browser": "8.0.0",
+    "@angular/platform-browser-dynamic": "8.0.0",
+    "@angular/router": "8.0.0",
+    "@fortawesome/fontawesome-free": "5.9.0",
+    "angular-tree-component": "8.4.0",
+    "angular2-text-mask": "9.0.0",
+    "angular2-toaster": "7.0.0",
+    "bootstrap": "4.3.1",
+    "chart.js": "2.8.0",
+    "classlist.js": "1.1.20150312",
+    "core-js": "2.5.4",
+    "echarts": "^4.6.0",
+    "enhanced-resolve": "4.1.0",
+    "intl": "1.2.5",
+    "jquery": "3.4.1",
+    "jquery-slimscroll": "1.3.8",
+    "jquery.browser": "0.1.0",
+    "lodash": "4.17.11",
+    "modernizr": "3.7.1",
+    "moment": "2.24.0",
+    "ng2-charts": "2.3.0",
+    "ng2-dnd": "5.0.2",
+    "ng2-file-upload": "1.3.0",
+    "ng2-img-cropper": "0.9.0",
+    "ng2-material-dropdown": "0.10.1",
+    "ngx-bootstrap": "4.3.0",
+    "ngx-color-picker": "8.0.0",
+    "ngx-cookie-service": "^2.3.0",
+    "ngx-echarts": "^4.2.2",
+    "ngx-infinite-scroll": "7.2.0",
+    "ngx-loading": "^3.0.1",
+    "ngx-order-pipe": "^2.0.4",
+    "ngx-select-ex": "3.6.10",
+    "ngx-viewer": "^1.0.5",
+    "popper.js": "1.15.0",
+    "rxjs": "6.5.2",
+    "rxjs-compat": "6.5.2",
+    "screenfull": "4.2.0",
+    "simple-line-icons": "2.4.1",
+    "source-sans-pro": "2.45.0",
+    "summernote": "0.8.12",
+    "sweetalert": "2.1.2",
+    "ts-helpers": "1.1.2",
+    "viewerjs": "^1.5.0",
+    "web-animations-js": "2.3.1",
+    "zone.js": "0.9.1"
+  },
+  "devDependencies": {
+    "@angular-devkit/build-angular": "0.800.2",
+    "@angular/cli": "8.0.2",
+    "@angular/compiler-cli": "8.0.0",
+    "@angular/language-service": "8.0.0",
+    "@types/jasmine": "2.8.8",
+    "@types/jasminewd2": "2.0.3",
+    "@types/jquery": "3.3.29",
+    "@types/lodash": "4.14.118",
+    "@types/node": "12.0.7",
+    "codelyzer": "5.1.0",
+    "jasmine-core": "2.99.1",
+    "jasmine-spec-reporter": "4.2.1",
+    "karma": "^4.4.1",
+    "karma-chrome-launcher": "2.2.0",
+    "karma-cli": "1.0.1",
+    "karma-coverage-istanbul-reporter": "2.0.1",
+    "karma-jasmine": "1.1.2",
+    "karma-jasmine-html-reporter": "0.2.2",
+    "karma-read-json": "1.1.0",
+    "loaders.css": "0.1.2",
+    "protractor": "5.4.2",
+    "ts-node": "8.2.0",
+    "tslint": "5.17.0",
+    "typescript": "3.4.5",
+    "webdriver-manager": "12.1.5"
+  }
+}

+ 5 - 0
proxy.conf.json

@@ -0,0 +1,5 @@
+{
+  "/sk":{
+    "target":"http://127.0.0.1:8080/"
+  }
+}

+ 3 - 0
src/app/app.component.html

@@ -0,0 +1,3 @@
+<router-outlet></router-outlet>
+<toaster-container [toasterconfig]="toasterconfig"></toaster-container>
+<ngx-loading [show]="isLoading"></ngx-loading>

+ 0 - 0
src/app/app.component.scss


+ 60 - 0
src/app/app.component.ts

@@ -0,0 +1,60 @@
+import { Component, HostBinding, OnInit } from '@angular/core';
+
+import { SettingsService } from './core/settings/settings.service';
+import {ToasterConfig, ToasterService} from 'angular2-toaster';
+import {MsgService} from './core/msg/msg.service';
+import {AjaxService} from './core/ajax/ajax.service';
+import {FrameService} from './core/frame/frame.service';
+import {DomSanitizer} from '@angular/platform-browser';
+
+@Component({
+    selector: 'app-root',
+    templateUrl: './app.component.html',
+    styleUrls: ['./app.component.scss']
+})
+export class AppComponent implements OnInit {
+
+    @HostBinding('class.layout-fixed') get isFixed() { return this.settings.getLayoutSetting('isFixed'); };
+    @HostBinding('class.aside-collapsed') get isCollapsed() { return this.settings.getLayoutSetting('isCollapsed'); };
+    @HostBinding('class.layout-boxed') get isBoxed() { return this.settings.getLayoutSetting('isBoxed'); };
+    @HostBinding('class.layout-fs') get useFullLayout() { return this.settings.getLayoutSetting('useFullLayout'); };
+    @HostBinding('class.hidden-footer') get hiddenFooter() { return this.settings.getLayoutSetting('hiddenFooter'); };
+    @HostBinding('class.layout-h') get horizontal() { return this.settings.getLayoutSetting('horizontal'); };
+    @HostBinding('class.aside-float') get isFloat() { return this.settings.getLayoutSetting('isFloat'); };
+    @HostBinding('class.offsidebar-open') get offsidebarOpen() { return this.settings.getLayoutSetting('offsidebarOpen'); };
+    @HostBinding('class.aside-toggled') get asideToggled() { return this.settings.getLayoutSetting('asideToggled'); };
+    @HostBinding('class.aside-collapsed-text') get isCollapsedText() { return this.settings.getLayoutSetting('isCollapsedText'); };
+
+    // 显示正在加载的框
+    isLoading: boolean = false;
+
+    // 右下角提示框
+    toasterconfig: ToasterConfig = new ToasterConfig({
+      positionClass: 'toast-bottom-right',
+      showCloseButton: true,
+      mouseoverTimerStop: true,
+      limit: 3
+    });
+
+    constructor(public settings: SettingsService, private toaster: ToasterService) {
+      MsgService.TOASTER = this.toaster;
+      MsgService.APP_COMPONENT = this;
+    }
+
+    ngOnInit() {
+        // 禁用所有的a超链接,所有超链接必须通过js代码打开新窗口
+        document.addEventListener('click', e => {
+            const target = e.target as HTMLElement;
+            if (target.tagName === 'A' || target.tagName === 'a') {
+              e.preventDefault();
+            };
+        });
+
+        // 禁止F5 刷新
+      document.addEventListener('keydown', e => {
+        if (e.key === 'F5')
+          e.preventDefault();
+          return false;
+      });
+    }
+}

+ 89 - 0
src/app/app.module.ts

@@ -0,0 +1,89 @@
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; // this is needed!
+import {enableProdMode, Injector, LOCALE_ID, NgModule} from '@angular/core';
+import {HttpClient, HttpClientModule} from '@angular/common/http';
+
+import {AppComponent} from './app.component';
+
+import {CoreModule} from './core/core.module';
+import {LayoutModule} from './layout/layout.module';
+import {SharedModule} from './shared/shared.module';
+import {RoutesModule} from './routes/routes.module';
+import {HashLocationStrategy, LocationStrategy, registerLocaleData} from '@angular/common';
+import {environment} from '../environments/environment';
+import * as $ from 'jquery';
+import {AjaxService} from './core/ajax/ajax.service';
+import {FrameService} from './core/frame/frame.service';
+import localeZh from '@angular/common/locales/zh';
+import {DomSanitizer} from '@angular/platform-browser';
+@NgModule({
+  declarations: [
+    AppComponent
+  ],
+  imports: [
+    HttpClientModule,
+    BrowserAnimationsModule,
+    CoreModule,
+    SharedModule.forRoot(),
+    LayoutModule,
+    RoutesModule
+  ],
+  providers: [{provide: LocationStrategy, useClass: HashLocationStrategy},{ provide: LOCALE_ID, useValue: 'zh-CN' }],
+  bootstrap: [AppComponent]
+})
+export class AppModule {
+  constructor(private injector: Injector, private httpClient: HttpClient,  private sanitizer: DomSanitizer) {
+
+    // 中文环境
+    registerLocaleData(localeZh);
+    AjaxService.injector = this.injector;
+    AjaxService.http = this.httpClient;
+    AjaxService.sanitizer = this.sanitizer;
+    // if (!environment.production) {
+    //   // develop mode ,auto login
+    //   $.ajax({
+    //     url: environment.webRoot + 'frame/optr/login.htm',
+    //     async: false,
+    //     type: 'POST',
+    //     dataType: 'json',
+    //     data: {
+    //       loginName: 'admin',
+    //       loginPass : '123456',
+    //       loginCode : '1234'
+    //     },
+    //     success: function (data) {
+    //       console.log('develop model ,auto login success!');
+    //     },
+    //     error : function () {
+    //       alert('develop model, tomcat not startup!');
+    //     }
+    //   });
+    // }
+
+    // login success, get param with not async
+    let init: boolean = false;
+    $.ajax({
+      url: environment.webRoot + 'frame/optr/init.htm',
+      async: false,
+      type: 'POST',
+      dataType: 'json',
+      success: function (data) {
+        if (data.success === false) {
+          window.location.href = './assets/login/login.html';
+          return;
+        }
+        FrameService.instance(data.map);
+        init = true;
+      },
+      error: function () {
+        alert('服务端未正常运行,请联系系统管理员!')
+        window.location.href = './assets/login/login.html';
+        return;
+      }
+    });
+
+    if (init === false) {
+      // window.location.href = './assets/login/login.html';
+      return;
+    }
+  }
+}

+ 1 - 0
src/app/core/ajax/ajax.component.html

@@ -0,0 +1 @@
+<ng-container></ng-container>

+ 158 - 0
src/app/core/ajax/ajax.component.ts

@@ -0,0 +1,158 @@
+import {Component, OnDestroy, OnInit, Input} from '@angular/core';
+import {AjaxService} from '../ajax/ajax.service';
+import {MsgService} from '../msg/msg.service';
+import {BsModalService} from 'ngx-bootstrap';
+
+@Component({
+  selector: 'frame-ajax',
+  templateUrl: './ajax.component.html'
+})
+export class AjaxComponent implements OnInit, OnDestroy {
+  @Input()
+  url: string;
+  @Input()
+  showLoading = false;
+  @Input()
+  ajaxType = 'Entity';
+  @Input()
+  autoRequest = true;
+  @Input()
+  requestData: {};
+  @Input()
+  requestParam: any;
+  @Input()
+  callback: Function;
+
+
+  private responseData: any;
+  private responseMap: any;
+  private responseArray: any;
+  private responseEntity: any;
+
+
+  private intervalId: any;
+
+
+  constructor(private bsService: BsModalService) {
+    this.responseData = {};
+    this.responseMap = {};
+    this.responseArray = [];
+    this.responseEntity = {};
+  }
+
+
+  getMap() {
+    return this.responseMap;
+  }
+
+  getArray() {
+    return this.responseArray;
+  }
+
+  getEntity() {
+    return this.responseEntity;
+  }
+
+  /**********************
+   * 另外独立的请求
+   */
+  request(url?: string, data?: {}, callback?: Function, param?: {}) {
+    const vUrl = url === undefined ? this.url : url;
+    const vData = Object.assign({}, this.requestData, data);
+    const vCallback = callback === undefined ? this.callback : callback;
+    const vParam = Object.assign({}, this.requestParam, param);
+
+    if (vParam.RequestType === undefined) {
+      vParam.RequestType = this.ajaxType;
+    }
+    AjaxService.request(vUrl, vData, (response) => {
+      if (vParam.RequestType === 'Entity') {
+        this.responseEntity = response;
+        if (vCallback) {
+          vCallback.call(this, response);
+        }
+      } else if (vParam.RequestType === 'Map') {
+        this.responseMap = response;
+        if (vCallback) {
+          vCallback.call(this, response);
+        }
+      } else if (vParam.RequestType === 'Array') {
+        this.responseArray = response;
+        if (vCallback) {
+          vCallback.call(this, response);
+        }
+      } else {
+        this.responseData = response;
+        if (vCallback) {
+          vCallback.call(this, response);
+        }
+      }
+    }, vParam);
+
+  }
+
+  reload(data?) {
+    this.request(undefined, data);
+  }
+
+  public optrRecord(url: string, data: {}, param?: { successMsg?: string, successMsgType?: string, confirmMsg?: string, callback?: Function }, options?: { RequestWithLoading?: boolean }) {
+
+    if (options === undefined) {
+      options = {};
+    }
+    if (options.RequestWithLoading === undefined) {
+      options.RequestWithLoading = true;
+    }
+
+    const confirmMsg = param ? param.confirmMsg : undefined;
+
+    const fn = () => {
+      AjaxService.request(url, data, (response) => {
+        // 判断是否是后台线程
+        if (response.threadId) {
+          // 如果返回的json有threadId,表示是一个后台线程
+          MsgService.showThreadRunning(this.bsService, response.entity, {threadTitle: '请求已提交,数据后台处理中......'}, param);
+        } else {
+          const successMsg = param ? (param.successMsg ? param.successMsg : '操作成功') : '操作成功';
+          if (successMsg) {
+            const successMsgType = param ? (param.successMsgType ? param.successMsgType : 'Toaster') : 'Toaster';
+
+            if (successMsgType === 'Toaster') {
+              MsgService.successToaster(successMsg);
+            } else if (successMsgType === 'Swal') {
+              MsgService.successAlert(successMsg);
+            } else {
+              alert(successMsg);
+            }
+          }
+          const callback = param ? param.callback : undefined;
+          if (callback) {
+            callback.call(this, data);
+          }
+        }
+      }, options);
+    };
+
+    if (confirmMsg) {
+      MsgService.confirm(confirmMsg, fn);
+    } else {
+      fn.call(this);
+    }
+
+  }
+
+  ngOnInit(): void {
+    if (this.autoRequest) {
+      setTimeout(() => {
+        this.request();
+      }, 10);
+
+    }
+
+  }
+
+  ngOnDestroy(): void {
+    clearTimeout(this.intervalId);
+  }
+
+}

+ 148 - 0
src/app/core/ajax/ajax.service.ts

@@ -0,0 +1,148 @@
+import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http';
+import {Injector} from '@angular/core';
+import {MsgService} from '../msg/msg.service';
+import {environment} from '../../../environments/environment';
+import {FrameService} from '../frame/frame.service';
+import {DomSanitizer} from '@angular/platform-browser';
+import {timeout} from 'rxjs/operators';
+
+export class AjaxService {
+
+  /**************************
+   * 所有的请求通用头部
+   */
+  private static HEADERS = new HttpHeaders()
+    .set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8')
+    .set('Accept', 'application/json, text/javascript, */*; q=0.01')
+    .set('X-Requested-With', 'XMLHttpRequest');
+
+  public static http: HttpClient;
+  public static injector: Injector;
+  public static sanitizer: DomSanitizer;
+
+
+  public static request(url: string, data: {}, callback?: Function, param?: {}) {
+    // 统一记上sessionId
+    if (data === undefined) {
+      data = {};
+    }
+    if (param === undefined) {
+      param = {};
+    }
+
+
+    data['FrameSessionId'] = FrameService.FrameSessionId;
+    for (const key in data) {
+      if (data[key] === 'undefined' ||  data[key] === undefined || data[key] === null) {
+        delete data[key];
+      }
+    }
+
+    const RequestWithLoading = param === undefined ? false : param['RequestWithLoading'];
+    if (RequestWithLoading) {
+      MsgService.showLoading();
+    }
+
+
+    AjaxService.http.post(environment.webRoot + url, new HttpParams({
+      fromObject: data
+    }), {headers: AjaxService.HEADERS}).pipe(timeout(60000))
+      .subscribe(
+        (response: any) => {
+          // 根据不同参数,返回不同的对象
+          if (response.success) {
+            let responseObj = response;
+            const requestType = param === undefined ? '' : param['RequestType'];
+            if (requestType === 'Entity') {
+              responseObj = response.entity;
+            } else if (requestType === 'Array') {
+              responseObj = response.array;
+            } else if (requestType === 'Page') {
+              responseObj = response.page;
+            } else if (requestType === 'Map') {
+              responseObj = response.map;
+            }
+            if (callback) {
+              callback.call(undefined, responseObj);
+            }
+          } else {
+            if (response['login'] === false) {
+              MsgService.errorAlert(response.errorMsg, undefined, () => {
+                window.location.href = './assets/login/login.html';
+              });
+              return;
+            }
+            const msgType = param['MsgType'] === undefined ? 'Toaster' : param['MsgType'];
+            const msgFlag = param['MsgFlag'] === undefined ? true : param['MsgFlag'];
+            const errorCallback = param['ErrorCallback'];
+            // 业务错误
+            // 是否需要提示错误信息
+            if (errorCallback) {
+              errorCallback.call(undefined, response);
+            }
+            if (msgFlag) {
+              if (msgType === 'Toaster') {
+                MsgService.errorToaster(response.errorMsg);
+              } else if (msgType === 'Swal') {
+                MsgService.errorAlert(response.errorMsg);
+              } else if (msgType === 'Alert') {
+                alert(response.errorMsg);
+              }
+            }
+          }
+        }, () => {
+          if (RequestWithLoading) {
+            MsgService.hideLoading();
+          }
+          const errorCallback = param['ErrorCallback'];
+          // 业务错误
+          // 是否需要提示错误信息
+          if (errorCallback) {
+            errorCallback.call(undefined);
+          }
+          // 未能正常请求,包括路径不存在 404错误,等其他非业务错误
+          MsgService.errorAlert('网络错误,请稍后重试!');
+        }, () => {
+          if (RequestWithLoading) {
+            MsgService.hideLoading();
+          }
+        });
+  }
+
+  public static requestEntity(url: string, data: {}, callback?: Function, param?: {}) {
+    const obj = Object.assign({}, param, {RequestType: 'Entity'});
+    return AjaxService.request(url, data, callback, obj);
+  }
+
+  public static requestArray(url: string, data: {}, callback?: Function, param?: {}) {
+    const obj = Object.assign({}, param, {RequestType: 'Array'});
+    return AjaxService.request(url, data, callback, obj);
+  }
+
+  public static requestMap(url: string, data: {}, callback?: Function, param?: {}) {
+    const obj = Object.assign({}, param, {RequestType: 'Map'});
+    return AjaxService.request(url, data, callback, obj);
+  }
+
+  public static requestPage(url: string, data: {}, callback?: Function, param?: {}) {
+    const obj = Object.assign({}, param, {RequestType: 'Page'});
+    return AjaxService.request(url, data, callback, obj);
+  }
+
+
+  // ajax下载
+  public static ajaxDownload(url: string, param?: any) {
+    let html = '<form action="' + environment.uploadRoot + url + '" method="post" target="_blank">';
+    for (const name in param) {
+      if (typeof (param[name]) !== 'function' && name !== '$$hashKey') {
+        const value = param[name];
+        if (value !== null && value !== undefined) {
+          html = html + '<input type="hidden" name="' + name + '" value="' + value + '"/>';
+        }
+
+      }
+    }
+    html = html + '</form>';
+    $(html).appendTo('body').submit().remove();
+  }
+}

+ 26 - 0
src/app/core/core.module.ts

@@ -0,0 +1,26 @@
+import { NgModule, Optional, SkipSelf } from '@angular/core';
+
+import { SettingsService } from './settings/settings.service';
+import { ThemesService } from './themes/themes.service';
+import { MenuService } from './menu/menu.service';
+
+import { throwIfAlreadyLoaded } from './module-import-guard';
+
+@NgModule({
+    imports: [
+    ],
+    providers: [
+        SettingsService,
+        ThemesService,
+        MenuService
+    ],
+    declarations: [
+    ],
+    exports: [
+    ]
+})
+export class CoreModule {
+    constructor( @Optional() @SkipSelf() parentModule: CoreModule) {
+        throwIfAlreadyLoaded(parentModule, 'CoreModule');
+    }
+}

+ 349 - 0
src/app/core/frame/frame.service.ts

@@ -0,0 +1,349 @@
+/********************
+ *  框架必须的参数、权限等信息
+ */
+import {AjaxService} from '../ajax/ajax.service';
+import {MenuService} from '../menu/menu.service';
+import {formatCurrency} from '@angular/common';
+
+export class FrameService {
+
+  // 初始化时返回的的参数
+  public static LoginInitMap: any;
+  // 系统字典
+  public static DictMap: any = {};
+  // 系统参数
+  public static ParamMap: any = {};
+  // 操作员
+  public static FrameOptr: any;
+  // 部门信息
+  public static FrameDept: any;
+  // 操作员资源信息
+  public static ResMap: any = {};
+  // 操作员资源信息
+  public static ResArray: [any];
+  // 全局session_id
+  public static FrameSessionId: any;
+
+  public static instance(map: any) {
+    FrameService.LoginInitMap = map;
+    // 系统字典
+    for (const v of map['FrameDictArray']) {
+      if (!FrameService.DictMap[v['dict_name']]) {
+        FrameService.DictMap[v['dict_name']] = new Array();
+      }
+      FrameService.DictMap[v['dict_name']].push(v);
+    }
+
+    // 系统参数
+    for (const v of map['FrameParamArray']) {
+      FrameService.ParamMap[v['param_name']] = v;
+    }
+    // 当前登录的用户
+    FrameService.FrameOptr = map['FrameOptr'];
+    FrameService.FrameDept = map['FrameDept'];
+    if (FrameService.FrameDept === undefined) {
+      FrameService.FrameDept = {dept_id: 0, dept_level: 0, dept_name: '顶级部门'};
+    }
+    if (FrameService.FrameOptr['optr_image'] === undefined) {
+      // 如果没有图片,设置默认图片
+      FrameService.FrameOptr['optr_image'] = `assets/img/user/01.jpg`;
+    }
+
+    // 操作员可用资源
+    const resArray = new Array();
+    // 所有权限
+    for (const v of map['FrameResArray']) {
+      FrameService.ResMap['R_' + v['res_id']] = v;
+      if (v['res_level'] === 1) {
+        FrameService.findChildRes(map['FrameResArray'], v);
+        resArray.push(v);
+      }
+    }
+    FrameService.ResArray = map['FrameResArray'];
+
+    // 所有菜单
+    const aMenu = new Array();
+    for (const v of resArray) {
+      if (v['childArray'] === undefined) {
+        continue;
+      }
+      // 添加顶层菜单
+      aMenu.push({
+        text: v['res_name'],
+        heading: true,
+        icon: v['res_css']
+      });
+      // 二级菜单
+      for (const c of v['childArray']) {
+        if (c['childArray'] && c['childArray'].length > 0) {
+          const dArray = new Array();
+          for (const d of c['childArray']) {
+            dArray.push({
+              text: d['res_name'],
+              link: d['res_url'],
+              icon: d['res_css']
+            });
+          }
+
+          aMenu.push({
+            text: c['res_name'],
+            link: c['res_url'],
+            icon: c['res_css'],
+            submenu: dArray
+          });
+        } else {
+          aMenu.push({
+            text: c['res_name'],
+            link: c['res_url'],
+            icon: c['res_css']
+          });
+        }
+      }
+
+    }
+
+    // 设置标题
+    if (FrameService.ParamMap['FrameName']) {
+      document.title = FrameService.ParamMap['FrameName']['param_value'];
+    }
+
+    // 设置sessionId
+    FrameService.FrameSessionId = map['FrameSessionId'];
+
+    // 添加菜单
+    const mService = AjaxService.injector.get<MenuService>(MenuService);
+    mService.addMenu(aMenu);
+  }
+
+
+  /********************
+   * 查找某个资源下的所有资源
+   */
+  public static findChildRes(resArray, res) {
+    const array = new Array();
+    for (const v of resArray) {
+      if (v['res_id'] !== res['res_id'] && v['res_pid'] === res['res_id'] && v['res_type'] !== 'Fun') {
+        FrameService.findChildRes(resArray, v);
+        array.push(v);
+        res.childArray = array;
+      }
+    }
+  }
+
+  /**********************
+   * 将某个res下的所有资源转为数组
+   */
+  public static makeResArray(res, array) {
+    if (res.childArray && res.childArray.length > 0) {
+      for (const c of res.childArray) {
+        array.push(c);
+        FrameService.makeResArray(c, array);
+      }
+    }
+  }
+
+
+  /**************************
+   * 获取某一个字典所有的字典项
+   * @param {string} dict_name  字典名称
+   * @returns {[any]} 项目数组
+   */
+  public static getFrameDictArray(dict_name: string): [any] {
+    return FrameService.DictMap[dict_name];
+  }
+
+
+  /***********************
+   * 获取字典项
+   * @param {string} dict_name 字典名称
+   * @param {string} dict_value 字典唯一值
+   * @returns {any} 对应的字典项
+   */
+  public static getFrameDict(dict_name: string, dict_value: string) {
+    if (dict_name !== undefined && FrameService.DictMap[dict_name] !== undefined) {
+      for (const v of FrameService.DictMap[dict_name]) {
+        if (v.dict_value === (dict_value + '')) {
+          return v;
+        }
+      }
+    }
+    return undefined;
+  }
+
+  /***********************
+   * 获取参数值
+   * @param {string} dict_name 字典名称
+   * @param {string} dict_value 字典唯一值
+   * @returns {any} 对应的字典项
+   */
+  public static getParamValue(param_name: string, default_value?: any) {
+    if (param_name !== undefined && FrameService.ParamMap[param_name] !== undefined) {
+      return FrameService.ParamMap[param_name].param_value;
+    }
+    if (default_value) {
+      return default_value + '';
+    }
+    return default_value;
+  }
+
+  /******************
+   * 获取字典的中文描述
+   * @param {string} dict_name  字典名称
+   * @param {string} dict_value 字典唯一值
+   * @returns {any} 对应的描述信息
+   */
+  public static getFrameDictText(dict_name: string, dict_value: string) {
+    const dict = FrameService.getFrameDict(dict_name, dict_value);
+    if (dict !== undefined) {
+      return dict.dict_text;
+    }
+    return dict_value;
+  }
+
+  /************************
+   * 验证是否有权限
+   * @param res 资源编号或者别名
+   * @returns {boolean} 是否有对应的权限
+   */
+  public static validateRole(res: any): boolean {
+    if (FrameService.FrameOptr === undefined) {
+      return false;
+    }
+    // 超级管理员
+    if (res === 0 || res === '0' || FrameService.FrameOptr.optr_role === 0) {
+      if (FrameService.FrameOptr.optr_role === 0) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    // 一般权限判断
+    for (const r of FrameService.ResArray) {
+      if (res === res.res_id || res === r.res_alias) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /********************
+   * 格式化中文货币
+   */
+  public static formatCurrency(v) {
+    return formatCurrency(v, 'zh', '¥');
+  }
+
+  /******************
+   * 将转字符串转化为日期
+   */
+  public static parseDate(v) {
+    return new Date(Date.parse(v.replace(/-/g, '/')));
+  }
+
+  /*********************
+   * 数组排序
+   * @param array 需要排序的数组
+   * @param attr_name 用来排序的字段
+   */
+  public static sortArray(array, attr_name, order_attr?: any) {
+    for (let i = 0; i < array.length - 1; i++) {
+      for (let j = 0; j < array.length - 1 - i; j++) {
+        if (array[j][attr_name] > array[j + 1][attr_name]) {
+          const temp = array[j];
+          array[j] = array[j + 1];
+          array[j + 1] = temp;
+        }
+      }
+      if (order_attr !== undefined) {
+        array[order_attr] = i + 1;
+      }
+    }
+  }
+
+
+  public static foramtDate(date, fmt) {
+    const o = {
+      'M+': date.getMonth() + 1,
+      'd+': date.getDate(),
+      'h+': date.getHours(),
+      'm+': date.getMinutes(),
+      's+': date.getSeconds(),
+      'q+': Math.floor((date.getMonth() + 3) / 3),
+      'S': date.getMilliseconds()
+    };
+    if (/(y+)/.test(fmt)) {
+      fmt = fmt.replace(RegExp.$1, (date.getFullYear() + ``).substr(4 - RegExp.$1.length));
+    }
+    for (var k in o) {
+      if (new RegExp(`(` + k + `)`).test(fmt)) {
+        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : ((`00` + o[k]).substr((`` + o[k]).length)));
+      }
+    }
+    return fmt;
+  }
+
+  public static longDateString(date) {
+    if (date instanceof Date) {
+      return FrameService.foramtDate(date, 'yyyy-MM-dd hh:mm:ss');
+    }
+    return '';
+  }
+
+  public static shortDateString(date) {
+    if (date === undefined) {
+      return '';
+    }
+    if (date instanceof Date) {
+      date = FrameService.foramtDate(date, 'yyyy-MM-dd hh:mm:ss');
+    }
+    if (date.length > 10)
+      return date.substr(0, 10);
+    return date;
+  }
+
+  public static shortTimeString(date) {
+    if (date === undefined) {
+      return '';
+    }
+    if (date instanceof Date) {
+      date = FrameService.foramtDate(date, 'yyyy-MM-dd hh:mm:ss');
+    }
+    if (date.length > 10) {
+      return date.substr(11);
+    }
+    return date;
+  }
+
+  public static shortMinuteString(date) {
+    if (date === undefined) {
+      return '';
+    }
+    if (date instanceof Date) {
+      date = FrameService.foramtDate(date, 'yyyy-MM-dd hh:mm:ss');
+    }
+    if (date.length > 10) {
+      return date.substr(11, 5);
+    }
+    return date;
+  }
+
+  public static parseShortString(date) {
+    if (date instanceof Date) {
+      return date;
+    }
+    return new Date(Date.parse(FrameService.shortDateString(date).replace(/-/g, '/')));
+  }
+
+  public static parseLongString(date) {
+    if (date instanceof Date) {
+      return date;
+    }
+    if (date === undefined || date.length !== 19) {
+      return undefined;
+    }
+    return new Date(Date.parse(date.replace(/-/g, `/`)));
+  }
+
+
+}

+ 31 - 0
src/app/core/menu/menu.service.ts

@@ -0,0 +1,31 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MenuService {
+
+    menuItems: Array<any>;
+
+    constructor() {
+        this.menuItems = [];
+    }
+
+    addMenu(items: Array<{
+        text: string,
+        heading?: boolean,
+        link?: string,     // internal route links
+        elink?: string,    // used only for external links
+        target?: string,   // anchor target="_blank|_self|_parent|_top|framename"
+        icon?: string,
+        alert?: string,
+        submenu?: Array<any>
+    }>) {
+        items.forEach((item) => {
+            this.menuItems.push(item);
+        });
+    }
+
+    getMenu() {
+        return this.menuItems;
+    }
+
+}

+ 6 - 0
src/app/core/module-import-guard.ts

@@ -0,0 +1,6 @@
+// https://angular.io/styleguide#!#04-12
+export function throwIfAlreadyLoaded(parentModule: any, moduleName: string) {
+  if (parentModule) {
+    throw new Error(`${moduleName} has already been loaded. Import Core modules in the AppModule only.`);
+  }
+}

+ 13 - 0
src/app/core/msg/form-msg/form-msg.component.html

@@ -0,0 +1,13 @@
+<span class="text-danger"
+      *ngIf="valForm?.controls[fieldName]?.hasError(errorCode) && (valForm?.controls[fieldName]?.dirty || valForm?.controls[fieldName]?.touched)">
+  <span *ngIf="errorMsg">{{errorMsg}}</span>
+  <span *ngIf="errorMsg === undefined">
+    <span *ngIf="errorCode === 'min'">此项最小值为【{{valForm.controls[fieldName].errors['min'].min}}】</span>
+    <span *ngIf="errorCode === 'max'">此项最大值为【{{valForm.controls[fieldName].errors['max'].max}}】</span>
+    <span *ngIf="errorCode === 'minLength'">此项需要最少【{{valForm.controls[fieldName].errors['minLength'].minLength}}】个字符</span>
+    <span *ngIf="errorCode === 'maxLength'">此项最长允许【{{valForm.controls[fieldName].errors['maxLength'].minLength}}】个字符</span>
+
+  </span>
+</span>
+
+

+ 45 - 0
src/app/core/msg/form-msg/form-msg.component.ts

@@ -0,0 +1,45 @@
+import {Component, OnInit, Input} from '@angular/core';
+import {AbstractControl, FormGroup} from '@angular/forms';
+
+@Component({
+  selector: 'form-msg',
+  templateUrl: './form-msg.component.html'
+})
+export class FormMsgComponent implements OnInit {
+  @Input()
+  valForm: FormGroup;
+  @Input()
+  fieldName: string;
+  @Input()
+  errorCode = 'required';
+  @Input()
+  errorMsg: string;
+
+
+  constructor() {
+
+  }
+
+  ngOnInit(): void {
+    if (this.errorMsg === undefined) {
+      if (this.errorCode === 'required') {
+        this.errorMsg = '此处为必填项';
+      } else if (this.errorCode === 'minlength') {
+        this.errorMsg = '字符太短';
+      } else if (this.errorCode === 'maxlength') {
+        this.errorMsg = '字符过长';
+      } else if (this.errorCode === 'max') {
+        this.errorMsg = '数字过大';
+      } else if (this.errorCode === 'min') {
+        this.errorMsg = '数字太小';
+      } else if (this.errorCode === 'datetime') {
+        this.errorMsg = '请使用 yyyy-MM-dd HH:mi:ss格式';
+      } else if (this.errorCode === 'date') {
+        this.errorMsg = '请使用 yyyy-MM-dd 格式';
+      }
+
+    }
+  }
+
+
+}

+ 127 - 0
src/app/core/msg/msg.service.ts

@@ -0,0 +1,127 @@
+import {ToasterService} from 'angular2-toaster';
+import {AppComponent} from '../../app.component';
+import {FrameThreadRunningComponent} from '../../routes/frame/thread/frame-thread-running/frame-thread-running.component';
+import {BsModalService} from 'ngx-bootstrap';
+
+/********************************
+ *  消息服务,包括右下脚消息,弹框服务
+ */
+// 加载弹框服务
+const swal = require('sweetalert');
+
+export class MsgService {
+
+  public static TOASTER: ToasterService = null;
+  public static APP_COMPONENT: AppComponent = null;
+
+  /********************
+   * 显示操作成功消息
+   */
+  public static successToaster(msg) {
+    MsgService.TOASTER.pop('success', '', msg);
+  }
+
+  /********************
+   * 显示错误信息
+   */
+  public static errorToaster(msg) {
+    MsgService.TOASTER.pop('error', '', msg);
+  }
+
+  /********************
+   * 显示警告信息
+   */
+  public static warnToaster(msg) {
+    MsgService.TOASTER.pop('warning', '', msg);
+  }
+
+  /********************
+   * 显示Loading
+   */
+  public static showLoading() {
+    MsgService.APP_COMPONENT.isLoading = true;
+  }
+
+  /********************
+   * 隐藏Loading
+   */
+  public static hideLoading() {
+    MsgService.APP_COMPONENT.isLoading = false;
+  }
+
+  public static confirm(msg, callback) {
+    swal(msg, {
+      buttons: {
+        cancel: `取消操作`,
+        catch: {
+          text: '确认操作',
+          value: 'catch',
+        }
+      },
+    })
+      .then((value) => {
+        switch (value) {
+          case 'catch':
+            swal.close();
+            callback();
+            break;
+        }
+      });
+  }
+
+  public static errorAlert(msg: string, title?: string, callback?: Function) {
+    swal({
+      title: title,
+      text: msg,
+      icon: 'error',
+      button: {
+        text: '知道了 ...',
+        value: true,
+        visible: true,
+        closeModal: true,
+      }
+    }).then((value) => {
+      if (callback) {
+        callback();
+      }
+    });
+  }
+
+  public static successAlert(msg: string, title?: string, callback?: Function) {
+    swal({
+      title: title,
+      text: msg,
+      icon: 'success',
+      button: {
+        text: '知道了 ...',
+        value: true,
+        visible: true,
+        closeModal: true,
+      }
+    }).then((value) => {
+      if (callback) {
+        callback();
+      }
+    });
+  }
+
+  public static showThreadRunning(bsService: BsModalService, thread: any, data?: any, param?: any) {
+    const modal = Object.assign({}, {
+      animated: true,
+      keyboard: false,
+      backdrop: true,
+      ignoreBackdropClick: true,
+      initialState: {},
+      class: 'modal-6'
+    });
+    if (!data) {
+      data = {};
+    }
+    modal.initialState = data;
+    // modal.initialState['FramePageComponent'] = this;
+    modal.initialState['frameThread'] = thread;
+    modal.initialState['threadParam'] = param;
+    bsService.show(FrameThreadRunningComponent, modal);
+
+  }
+}

+ 55 - 0
src/app/core/pager/pager.component.html

@@ -0,0 +1,55 @@
+<div class="row wd-wide">
+  <div class="col-xl-3 col-md-3">
+    <div class="input-group" *ngIf="showSearch">
+      <input class="form-control ml-2" [style.width]="searchWidth + 'px;'" type="text" [(ngModel)]="query" [readonly]="dataLoading"
+             (keyup)="goSearch($event)" placeholder="模糊查询"/>
+      <div class="input-group-append">
+        <button class="btn btn-outline-secondary bg-white" (click)="goSearch()" [disabled]="dataLoading"><em class="fa fas fa-search"></em>
+        </button>
+      </div>
+    </div>
+  </div>
+
+  <div class="col-lg-9 col-md-9 ">
+    <div class="row float-right">
+      <div class="mt-2">
+        <div class="row">
+          <div class="input-group">每页
+            <input type="text" [(ngModel)]="pagerLimit" [readonly]="!allowChangePagerLimit"
+                   [style.width]="getPageLimitWidth()" (keyup)="changePageLimit($event)"
+                   style="text-align:center; margin-left:2px; margin-top: -2px; border:0px; background-color: transparent">条&nbsp;
+            第<input type="text" [(ngModel)]="pageIndex" (keyup)="changePageIndex($event)"
+                    [style.width]="getPageIndexWidth()" [readonly]="!allowChangePagerCurrent"
+                    style="text-align:center;margin-left:2px; margin-top: -2px; border:0px; background-color: transparent">页,
+            共{{pageTotal}}页({{recordTotal}}条数据)
+          </div>
+        </div>
+      </div>
+      <div class="mt-1 ml-4 align-items-center justify-content-center" *ngIf="dataLoading">
+        <div class="semi-circle-spin" style="width:20px;height:20px;">
+          <div style="background-color: black"></div>
+        </div>
+      </div>
+      <ul [class]="dataLoading === true?'pagination ml-2':'pagination ml-4'" *ngIf="showPagination && !dataLoading">
+        <li class="pagination-first page-item" *ngIf="showFirst"><a class="page-link" href="#" (click)="goFirst()"><em
+          class="fa fas fa-fast-backward"></em></a></li>
+        <li class="pagination-prev page-item" *ngIf="hasPrevGroup"><a class="page-link" href="#"
+                                                                      (click)="goPrevGroup()"><em
+          class="fa fa-angle-double-left"></em></a></li>
+        <ng-container *ngFor="let pg of pages">
+          <li [class.active]="pg.active" [class.disabled]="disabled&&!pg.active" *ngIf="pg.data"
+              class="pagination-page page-item">
+            <a class="page-link" [innerHTML]="pg.number" href="#" (click)="goPage(pg)"></a>
+          </li>
+        </ng-container>
+        <li class="pagination-next page-item" *ngIf="hasNextGroup"><a class="page-link" href="#"
+                                                                      (click)="goNextGroup()"><em
+          class="fa fa-angle-double-right"></em></a></li>
+        <li class="pagination-last page-item" *ngIf="showLast"><a class="page-link" href="#" (click)="goLast()"><em
+          class="fa fas fa-fast-forward"></em></a></li>
+      </ul>
+
+    </div>
+  </div>
+
+</div>

+ 382 - 0
src/app/core/pager/pager.component.ts

@@ -0,0 +1,382 @@
+import {Component, OnDestroy, OnInit, Input, Output, EventEmitter} from '@angular/core';
+import {CookieService} from 'ngx-cookie-service';
+import {FrameService} from '../frame/frame.service';
+import {AjaxService} from '../ajax/ajax.service';
+import {MsgService} from '../msg/msg.service';
+
+@Component({
+  selector: 'frame-pager',
+  templateUrl: './pager.component.html'
+})
+export class PagerComponent implements OnInit, OnDestroy {
+  @Input()
+  searchClass: {};
+  @Input()
+  searchStyle = {'width': '60px'};
+  @Input()
+  pagerLength = 10;
+  @Input()
+  pagerLimit: number;
+  @Input()
+  allowChangePagerLimit = true;
+  @Input()
+  allowChangePagerCurrent = true;
+  @Input()
+  showSearch = true;
+  @Input()
+  showPagination = true;
+  @Input()
+  url: string;
+  @Input()
+  pagerParams: {};
+  @Input()
+  autoRequest = true;
+  @Input()
+  showLoading = false;
+  @Input()
+  loopRequestTicket = 0;
+
+  @Output()
+  pagerChange = new EventEmitter<any>();
+  @Output()
+  recordChange = new EventEmitter<any>();
+
+  // 开始的记录条数
+  pageStart = 1;
+  // 当前第几页
+  pageIndex = 1;
+  // 总的页码
+  pageTotal = 1;
+  // 总记录数
+  recordTotal = 0;
+  // 是否有下一组页面
+  hasNextGroup = false;
+  // 是否有前一组页面
+  hasPrevGroup = false;
+  // 是否显示第一个页
+  showFirst = false;
+  // 是否显示最后一页
+  showLast = false;
+
+  // 查询
+  query: string;
+  // 排序字段
+  orderColumn = '';
+  // 排序方式
+  orderType = '';
+
+  // 总组数
+  private totalGroup = 0;
+  private currentGroup = 0;
+  // 所有分页数据
+  private pages: any;
+  // 当前分页数据
+  private records: any;
+  private cookieName_PageLimit = 'Frame.PagerLimit';
+
+  // 是否正在加载数据
+  dataLoading = false;
+
+  private intervalId: any;
+
+
+  constructor(private cookie: CookieService) {
+    this.pages = [];
+    this.records = [];
+  }
+
+  ngOnInit(): void {
+    // 取每页多少条记录
+    if (this.pagerLimit === undefined) {
+      // 如果没有指定当前页面记录数,先从cookies获取
+      if (this.cookie.get(this.cookieName_PageLimit)) {
+        // 如果cookies有数据
+        this.pagerLimit = parseInt(this.cookie.get(this.cookieName_PageLimit), 10);
+      } else {
+        // cookie没有数据,从系统获取
+        if (FrameService.ParamMap['FramePageLimit']) {
+          this.pagerLimit = parseInt(FrameService.ParamMap['FramePageLimit']['param_value'], 10);
+        }
+      }
+      if (this.pagerLimit === undefined || isNaN(this.pagerLimit)) {
+        this.pagerLimit = 20;
+      }
+    }
+
+    // 初始化分页的页面数
+    for (let i = 0; i < this.pagerLength; i++) {
+      this.pages.push({
+        active: false,
+        number: i + 1,
+        data: false
+      });
+    }
+
+    if (this.autoRequest) {
+      setTimeout(() => {
+        this.requestData();
+      }, 1);
+    }
+  }
+
+  // 数据加载,实际的分页请求
+  private requestData(params?: {}) {
+    if (this.url === '' || this.url === undefined) {
+      return;
+    }
+    const rData = Object.assign({}, this.pagerParams, params);
+    rData['limit'] = this.pagerLimit;
+    rData['start'] = this.pageStart - 1;
+    if (this.query && this.query.trim().length > 0) {
+      rData['query'] = this.query;
+    }
+    if (this.orderColumn !== '') {
+      rData['order'] = this.orderColumn;
+    }
+    if (this.orderType !== '') {
+      rData['type'] = this.orderType;
+    }
+
+    this.dataLoading = true;
+    AjaxService.requestPage(this.url, rData, (page) => {
+        page.index = page.index + 1;
+        this.pageIndex = page.index;
+        // 总记录数
+        this.recordTotal = page.total;
+
+        // 记录
+        this.records = page.records;
+
+        // 总页数
+        this.pageTotal = page.count;
+        // 当前页面
+        const pIndex = page.index;
+        // 计算在第几组
+        this.totalGroup = Math.ceil(page.count / this.pagerLength);
+        // 当前分组
+        this.currentGroup = Math.ceil(page.index / this.pagerLength);
+
+        // 如果是第一分组,不显示
+        if (this.currentGroup === 1) {
+          this.hasPrevGroup = false;
+          this.showFirst = false;
+        } else {
+          this.hasPrevGroup = true;
+          this.showFirst = true;
+        }
+
+        // 判断是否显示最后一组
+        if (this.currentGroup >= this.totalGroup) {
+          this.hasNextGroup = false;
+          this.showLast = false;
+        } else {
+          this.hasNextGroup = true;
+          this.showLast = true;
+        }
+
+        for (let i = 0; i < this.pagerLength; i++) {
+          const pageNumber = (this.currentGroup - 1) * this.pagerLength + 1 + i;
+          this.pages[i] = {
+            active: pageNumber === pIndex ? true : false,
+            number: pageNumber,
+            data: pageNumber <= this.pageTotal ? true : false
+          };
+        }
+        this.dataLoading = false;
+        // 判断是否需要间隔获取数据
+        if (this.loopRequestTicket > 0 && this.intervalId === undefined) {
+          this.intervalId = setInterval(this.reload.bind(this), this.loopRequestTicket * 1000);
+        }
+        this.pagerChange.emit(page);
+        // console.log(page);
+      }, {
+        'RequestWithLoading': this.showLoading,
+        'ErrorCallback': () => {
+          this.dataLoading = false;
+          // 判断是否需要间隔获取数据
+          if (this.loopRequestTicket > 0 && this.intervalId === undefined) {
+            this.intervalId = setInterval(this.reload.bind(this), this.loopRequestTicket * 1000);
+          }
+        }
+      }
+    );
+  }
+
+  // 修改每页条数
+  changePageLimit(event) {
+    if (event.keyCode === 13) {
+      const temp = parseInt(`${this.pageIndex}`, 10);
+      if (isNaN(temp) || temp < 1) {
+        this.pageIndex = 1;
+      } else {
+        this.pageIndex = temp;
+      }
+      this.pageStart = 1;
+      this.requestData();
+      this.cookie.set(this.cookieName_PageLimit, `${this.pagerLimit}`);
+    }
+  }
+
+  // 修改当前页面
+  changePageIndex(event) {
+    if (event.keyCode === 13) {
+      const temp = parseInt(this.pageIndex + '', 10);
+      if (isNaN(temp) || temp < 1) {
+        this.pageIndex = 1;
+      } else if (this.pageIndex > this.pageIndex) {
+        this.pageIndex = temp;
+      } else {
+        this.pageIndex = temp;
+      }
+
+      this.pageStart = (this.pageIndex - 1) * this.pagerLimit + 1;
+      this.requestData();
+    }
+  }
+
+  // 敲回车或者点击查询按钮
+  goSearch(event) {
+    if (event) {
+      if (event.keyCode !== 13) {
+        return;
+      }
+    }
+    this.pageStart = 1;
+    this.requestData();
+  }
+
+  // 点击页面跳转
+  goPage(page) {
+    // 开始页面
+    this.pageStart = (page.number - 1) * this.pagerLimit + 1;
+    this.requestData();
+  }
+
+  // 跳转到第一页
+  goFirst() {
+    this.pageStart = 1;
+    this.requestData();
+  }
+
+  // 跳转到最后一页
+  goLast() {
+    this.pageStart = (this.pageTotal - 1) * this.pagerLimit + 1;
+    this.requestData();
+  }
+
+  // 跳转到上一组
+  goPrevGroup() {
+    this.pageStart = ((this.currentGroup - 2) * this.pagerLength) * this.pagerLimit + 1;
+    this.requestData();
+  }
+
+  // 跳转到下一组
+  goNextGroup() {
+    this.pageStart = (this.currentGroup * this.pagerLength) * this.pagerLimit + 1;
+    this.requestData();
+  }
+
+// 排序
+  public sort(column) {
+    if (column === this.orderColumn) {
+      if (this.orderType === 'ASC') {
+        this.orderType = 'DESC';
+      } else {
+        this.orderType = 'ASC';
+      }
+    } else {
+      this.orderColumn = column;
+      this.orderType = 'ASC';
+    }
+    this.pageStart = 1;
+    this.requestData();
+  }
+
+  // 重新加载
+  public reload(param?: any) {
+    this.requestData(param);
+  }
+
+  // 清除数据
+  public clear(): void {
+    this.records = [];
+    this.pageStart = 1;
+    // 当前第几页
+    this.pageIndex = 1;
+    // 总的页码
+    this.pageTotal = 1;
+    // 总记录数
+    this.recordTotal = 0;
+    // 是否有下一组页面
+    this.hasNextGroup = false;
+    // 是否有前一组页面
+    this.hasPrevGroup = false;
+    // 是否显示第一个页
+    this.showFirst = false;
+    // 是否显示最后一页
+    this.showLast = false;
+    // 总组数
+    this.totalGroup = 0;
+    this.currentGroup = 0;
+  }
+
+  getPageLimitWidth() {
+    return (8 + (this.pagerLimit + '').length * 6) + 'px';
+  }
+
+  getPageIndexWidth() {
+    return (8 + (this.pageIndex + '').length * 6) + 'px';
+  }
+
+  // 获取记录
+  public getRecords(): [any] {
+    return this.records;
+  }
+
+  // 删除数据
+  public optrRecord(url: string, data: {}, param?: { successMsg?: string, successMsgType?: string, confirmMsg?: string, callback?: Function }, options?: { RequestWithLoading?: boolean }) {
+    if (options === undefined) {
+      options = {};
+    }
+    if (options.RequestWithLoading === undefined) {
+      options.RequestWithLoading = true;
+    }
+
+    const confirmMsg = param ? param.confirmMsg : undefined;
+
+    const fn = () => {
+      AjaxService.request(url, data, () => {
+        const successMsg = param ? (param.successMsg ? param.successMsg : '操作成功') : '操作成功';
+        if (successMsg) {
+          const successMsgType = param ? (param.successMsgType ? param.successMsgType : 'Toaster') : 'Toaster';
+          if (successMsgType === 'Toaster') {
+            MsgService.successToaster(successMsg);
+          } else if (successMsgType === 'Swal') {
+            MsgService.successAlert(successMsg);
+          } else {
+            alert(successMsg);
+          }
+        }
+        this.reload();
+        this.recordChange.emit(data);
+        const callback = param ? param.callback : undefined;
+        if (callback) {
+          callback.call(undefined, data);
+        }
+      }, options);
+    };
+
+    if (confirmMsg) {
+      MsgService.confirm(confirmMsg, fn);
+    } else {
+      fn.call(undefined);
+    }
+
+  }
+
+
+  ngOnDestroy(): void {
+    clearTimeout(this.intervalId);
+  }
+
+}

+ 3 - 0
src/app/core/preloader/preloader.component.html

@@ -0,0 +1,3 @@
+<div class="preloader-progress">
+  <div class="preloader-progress-bar" [style.width]="loadCounter+'%'"></div>
+</div>

+ 51 - 0
src/app/core/preloader/preloader.js

@@ -0,0 +1,51 @@
+(function(global) {
+
+    var counter = 0, timeout;
+    var preloader = document.querySelector('.preloader');
+    var progressBar = document.querySelector('.preloader-progress-bar');
+    var body = document.querySelector('body');
+
+    // if preloader not present => abort
+    if (!preloader) return;
+
+    // disables scrollbar
+    body.style.overflow = 'hidden';
+
+    timeout = setTimeout(startCounter, 20);
+
+    // main.ts call this function once the app is boostrapped
+    global.appBootstrap = function() {
+        setTimeout(endCounter, 1000);
+    };
+
+    function startCounter() {
+        var remaining = 100 - counter;
+        counter = counter + (0.015 * Math.pow(1 - Math.sqrt(remaining), 2));
+
+        if (progressBar) progressBar.style.width = Math.round(counter) + '%';
+
+        timeout = setTimeout(startCounter, 20);
+    }
+
+    function endCounter() {
+
+        clearTimeout(timeout);
+
+        if (progressBar) progressBar.style.width = '100%';
+
+        setTimeout(function() {
+            // animate preloader hiding
+            removePreloader();
+            // retore scrollbar
+            body.style.overflow = '';
+        }, 300);
+    }
+
+    function removePreloader() {
+        preloader.addEventListener('transitionend', function() {
+            preloader.className = 'preloader-hidden';
+        });
+        preloader.className += ' preloader-hidden-add preloader-hidden-add-active';
+    };
+
+})(window);

+ 71 - 0
src/app/core/preloader/preloader.scss

@@ -0,0 +1,71 @@
+/* ========================================================================
+   Component: preloader
+ ========================================================================== */
+@import "../../shared/styles/bootstrap/_functions.scss";
+@import "../../shared/styles/bootstrap/_variables.scss";
+@import "../../shared/styles/bootstrap/_mixins";
+@import "../../shared/styles/app/variables";
+
+$preloader-bg: $info;
+$preloader-wd: 100px;
+$preloader-hg: 30px;
+
+/*@noflip*/
+.preloader {
+    position: fixed;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    overflow: hidden;
+    background-color: $preloader-bg;
+    background-image: -webkit-linear-gradient(90deg, $preloader-bg 10%, darken($preloader-bg, 5%) 90%); /* Chrome 10+, Saf5.1+ */
+    background-image: -moz-linear-gradient(90deg, $preloader-bg 10%, darken($preloader-bg, 5%) 90%); /* FF3.6+ */
+    background-image: -ms-linear-gradient(90deg, $preloader-bg 10%, darken($preloader-bg, 5%) 90%); /* IE10 */
+    background-image: -o-linear-gradient(90deg, $preloader-bg 10%, darken($preloader-bg, 5%) 90%); /* Opera 11.10+ */
+    background-image: linear-gradient(90deg, $preloader-bg 10%, darken($preloader-bg, 5%) 90%); /* W3C */
+    z-index: 9999;
+    transition: opacity .65s;
+}
+
+/*@noflip*/
+.preloader-progress {
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    width: $preloader-wd;
+    height: $preloader-hg;
+    margin: auto;
+    overflow: auto;
+    background-image: url(../../../assets/img/preloader/preloader.empty.png);
+    background-size: $preloader-wd $preloader-hg;
+}
+
+/*@noflip*/
+.preloader-progress-bar {
+    position: absolute;
+    top: 0;
+    left: 0;
+    bottom: 0;
+    min-width: 10px;
+    background-image: url(../../../assets/img/preloader/preloader.full.png);
+    background-size: $preloader-wd $preloader-hg;
+}
+.preloader-hidden {
+    display: none;
+}
+// ngAnimate behavior
+.preloader-hidden-add {
+    opacity: 1;
+    display: block;
+
+    .preloader-progress {
+        transition: transform .4s ease;
+        transform: scale(0);
+    }
+}
+.preloader-hidden-add-active {
+    opacity: 0;
+}

+ 66 - 0
src/app/core/settings/settings.service.ts

@@ -0,0 +1,66 @@
+import {Injectable} from '@angular/core';
+import {FrameService} from '../frame/frame.service';
+import {CookieService} from 'ngx-cookie-service';
+
+@Injectable()
+export class SettingsService {
+
+  private user: any;
+  private app: any;
+  private layout: any;
+
+
+  constructor(public cookie: CookieService) {
+
+    // User Settings
+    // -----------------------------------
+    this.user = FrameService.FrameOptr;
+    // App Settings
+    // -----------------------------------
+    this.app = {
+      name: '禾木后台管理框架',
+      description: ''
+    };
+    this.layout = {
+      isFixed: this.cookie.get('frame.layout.isFixed') ? this.cookie.get('frame.layout.isFixed') : true,
+      isCollapsed: false,
+      isBoxed:  this.cookie.get('frame.layout.isBoxed') ? this.cookie.get('frame.layout.isBoxed') : false,
+      isRTL:  this.cookie.get('frame.layout.isRTL') ? this.cookie.get('frame.layout.isRTL') : false,
+      horizontal:  this.cookie.get('frame.layout.horizontal') ? this.cookie.get('frame.layout.horizontal') : false,
+      isFloat:  this.cookie.get('frame.layout.isFloat') ? this.cookie.get('frame.layout.isFloat') : false,
+      asideHover:  this.cookie.get('frame.layout.asideHover') ? this.cookie.get('frame.layout.asideHover') : false,
+      theme:  this.cookie.get('frame.layout.theme') ? this.cookie.get('frame.layout.theme') : null,
+      asideScrollbar:  this.cookie.get('frame.layout.asideScrollbar') ? this.cookie.get('frame.layout.asideScrollbar') : false,
+      isCollapsedText:  this.cookie.get('frame.layout.isCollapsedText') ? this.cookie.get('frame.layout.isCollapsedText') : false,
+      useFullLayout:  this.cookie.get('frame.layout.useFullLayout') ? this.cookie.get('frame.layout.useFullLayout') : false,
+      hiddenFooter:  this.cookie.get('frame.layout.hiddenFooter') ? this.cookie.get('frame.layout.hiddenFooter') : false,
+      offsidebarOpen: false,
+      asideToggled:  this.cookie.get('frame.layout.asideToggled') ? this.cookie.get('frame.layout.asideToggled') : false,
+      viewAnimation: this.cookie.get('frame.layout.viewAnimation') ? this.cookie.get('frame.layout.viewAnimation') : 'ng-fadeInUp'
+    };
+  }
+
+  getAppSetting(name) {
+    return name ? this.app[name] : this.app;
+  }
+
+  getUserSetting(name) {
+    return name ? this.user[name] : this.user;
+  }
+
+  getLayoutSetting(name) {
+    return name ? this.layout[name] : this.layout;
+  }
+
+  setLayoutSetting(name, value) {
+    if (typeof this.layout[name] !== 'undefined') {
+      this.cookie.set('frame.layout.' + name, value);
+      return this.layout[name] = value;
+    }
+  }
+
+  toggleLayoutSetting(name) {
+    return this.setLayoutSetting(name, !this.getLayoutSetting(name));
+  }
+
+}

+ 68 - 0
src/app/core/themes/themes.service.ts

@@ -0,0 +1,68 @@
+import { Injectable } from '@angular/core';
+
+const themeA = require('../../shared/styles/themes/theme-a.scss');
+const themeB = require('../../shared/styles/themes/theme-b.scss');
+const themeC = require('../../shared/styles/themes/theme-c.scss');
+const themeD = require('../../shared/styles/themes/theme-d.scss');
+const themeE = require('../../shared/styles/themes/theme-e.scss');
+const themeF = require('../../shared/styles/themes/theme-f.scss');
+const themeG = require('../../shared/styles/themes/theme-g.scss');
+const themeH = require('../../shared/styles/themes/theme-h.scss');
+
+@Injectable()
+export class ThemesService {
+
+    styleTag: any;
+    defaultTheme: string = 'A';
+
+    constructor() {
+        this.createStyle();
+        this.setTheme(this.defaultTheme);
+    }
+
+    private createStyle() {
+        const head = document.head || document.getElementsByTagName('head')[0];
+        this.styleTag = document.createElement('style');
+        this.styleTag.type = 'text/css';
+        this.styleTag.id = 'appthemes';
+        head.appendChild(this.styleTag);
+    }
+
+    setTheme(name) {
+        switch (name) {
+            case 'A':
+                this.injectStylesheet(themeA);
+                break;
+            case 'B':
+                this.injectStylesheet(themeB);
+                break;
+            case 'C':
+                this.injectStylesheet(themeC);
+                break;
+            case 'D':
+                this.injectStylesheet(themeD);
+                break;
+            case 'E':
+                this.injectStylesheet(themeE);
+                break;
+            case 'F':
+                this.injectStylesheet(themeF);
+                break;
+            case 'G':
+                this.injectStylesheet(themeG);
+                break;
+            case 'H':
+                this.injectStylesheet(themeH);
+                break;
+        }
+    }
+
+    injectStylesheet(css) {
+        this.styleTag.innerHTML = css;
+    }
+
+    getDefaultTheme() {
+        return this.defaultTheme;
+    }
+
+}

+ 4 - 0
src/app/core/uploader/uploader.component.html

@@ -0,0 +1,4 @@
+<div [hidden]="true">
+  <input #elMultipleUpload id="elMultFile" type="file" ng2FileSelect [uploader]="fileUploader" multiple/>
+  <input #elSimpleUpload id="elSimpleFile" type="file" ng2FileSelect [uploader]="fileUploader" />
+</div>

+ 149 - 0
src/app/core/uploader/uploader.component.ts

@@ -0,0 +1,149 @@
+import {Component, ElementRef, EventEmitter, Input, OnInit, Output, TemplateRef, ViewChild} from '@angular/core';
+import {FileItem, FileUploader, ParsedResponseHeaders} from 'ng2-file-upload';
+import {MsgService} from '../msg/msg.service';
+import {environment} from '../../../environments/environment';
+import {BsModalRef, BsModalService} from 'ngx-bootstrap';
+import {AjaxService} from '../ajax/ajax.service';
+
+@Component({
+  selector: 'frame-uploader',
+  templateUrl: './uploader.component.html'
+})
+export class UploaderComponent implements OnInit {
+  @Input() uploadUrl: string;
+  @Input() multiple = false;
+  @Input() confirmMsg: string;
+  @Input() successMsg: string;
+  @Input() allowedFileType: [string];
+  @Input() maxFileSize: number;
+  @Input() uploadParams = {};
+  @Input() templateFile: string;
+
+  @Output() afterUpload = new EventEmitter<any>();
+  @Output() beforeUpload = new EventEmitter<FileItem>();
+  @Output() allUpload = new EventEmitter<any>();
+
+  private requestparam: any;
+  private threadId; any;
+  private errorFlag = false;
+
+  // 上传核心组件
+  fileUploader: FileUploader;
+  @ViewChild('elSimpleUpload', {static: false}) elSimpleUpload: ElementRef;
+  @ViewChild('elMultipleUpload', {static: false}) elMultipleUpload: ElementRef;
+
+  constructor(private bsService: BsModalService) {
+  }
+
+  ngOnInit(): void {
+    this.fileUploader = new FileUploader({
+      url: environment.uploadRoot + this.uploadUrl,
+      allowedFileType: this.allowedFileType,
+      method: 'post',
+      maxFileSize: this.maxFileSize * 1024,
+      isHTML5: true,
+      autoUpload: true,
+      removeAfterUpload: true
+      // headers: [{ name: 'Access-Control-Allow-Origin', value: '*'}]
+    });
+    this.fileUploader.onBuildItemForm = this.onBuildItemForm.bind(this);
+    this.fileUploader.onBeforeUploadItem = this.onBeforeUploadItem.bind(this);
+    this.fileUploader.onCompleteItem = this.onCompleteItem.bind(this);
+    this.fileUploader.onCompleteAll = this.onCompleteAll.bind(this);
+    this.fileUploader.onAfterAddingAll = this.onAfterAddingAll.bind(this);
+  }
+
+  // 上传之前传递参数
+  private onBuildItemForm(fileItem: FileItem, form: any) {
+    fileItem.withCredentials = false;
+    const data = Object.assign({}, this.uploadParams, this.requestparam);
+    for (const v in data) {
+      form.append(v, data[v]);
+    }
+  }
+
+  private onBeforeUploadItem(fileItem: FileItem) {
+    this.beforeUpload.emit(fileItem);
+  }
+
+  private onAfterAddingAll() {
+    MsgService.showLoading();
+  }
+
+  private onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders) {
+    if (status === 404) {
+      MsgService.errorAlert(`无法访问上传地址,请联系系统管理员!`);
+      return;
+    }
+
+    if (status !== 200) {
+      // 非正常返回,直接提示错误信息、
+      MsgService.errorAlert(`文件上传出现异常,请稍后再试!`);
+      return;
+    }
+    const ajax = JSON.parse(response);
+    if (ajax.success === undefined || ajax.success === false) {
+      MsgService.errorAlert(ajax.errorMsg);
+      this.errorFlag = true;
+    } else {
+
+      // 判断是否是后台线程
+      if (ajax.threadId) {
+        this.threadId = ajax.threadId;
+        // 如果返回的json有threadId,表示是一个后台线程
+        MsgService.showThreadRunning(this.bsService, ajax.entity, {threadTitle: '文件已上传,正在解析处理'});
+      }
+      this.errorFlag = false;
+      this.afterUpload.emit(ajax);
+    }
+
+
+  }
+
+  private onCompleteAll() {
+    if (this.multiple === true) {
+      this.elMultipleUpload.nativeElement.value = '';
+    } else {
+      this.elSimpleUpload.nativeElement.value = '';
+    }
+
+    // 只有非线程的时候弹出提示信息
+    if (!this.errorFlag && this.successMsg !== undefined && this.threadId === undefined) {
+      MsgService.successAlert(this.successMsg);
+      this.allUpload.emit(undefined);
+    }
+    MsgService.hideLoading();
+
+  }
+
+  /******************
+   * 上传文件
+   */
+  uploadFiles(data?: any) {
+    const fn = () => {
+      this.requestparam = data;
+      if (this.multiple === true) {
+        this.elMultipleUpload.nativeElement.click();
+      } else {
+        this.elSimpleUpload.nativeElement.click();
+      }
+    };
+    if (this.confirmMsg !== undefined) {
+      MsgService.confirm(this.confirmMsg, fn);
+    } else {
+      fn.apply(undefined);
+    }
+  }
+
+
+  downloadTempalte(fileName?: string) {
+    if (fileName === undefined) {
+      fileName = this.templateFile;
+    }
+    if (fileName === undefined) {
+      return;
+    }
+
+    AjaxService.ajaxDownload('frame/template/download.htm', {file_name: fileName});
+  }
+}

+ 436 - 0
src/app/core/wrapper/wrapper.js

@@ -0,0 +1,436 @@
+/**
+ * This library was created to emulate some jQuery features
+ * used in this template only with Javascript and DOM
+ * manipulation functions (IE10+).
+ * All methods were designed for an adequate and specific use
+ * and don't perform a deep validation on the arguments provided.
+ *
+ * IMPORTANT:
+ * ==========
+ * It's suggested NOT to use this library extensively unless you
+ * understand what each method does. Instead, use only JS or
+ * you might even need jQuery.
+ */
+
+(function(global, factory) {
+    if (typeof exports === 'object') { // CommonJS-like
+        module.exports = factory();
+    } else { // Browser
+        if (typeof global.jQuery === 'undefined')
+            global.$ = factory();
+    }
+}(this, function() {
+
+    // HELPERS
+    function arrayFrom(obj) {
+        return ('length' in obj) && (obj !== window) ? [].slice.call(obj) : [obj];
+    }
+
+    function filter(ctx, fn) {
+        return [].filter.call(ctx, fn);
+    }
+
+    function map(ctx, fn) {
+        return [].map.call(ctx, fn);
+    }
+
+    function matches(item, selector) {
+        return (Element.prototype.matches || Element.prototype.msMatchesSelector).call(item, selector)
+    }
+
+    // Events handler with simple scoped events support
+    var EventHandler = function() {
+        this.events = {};
+    }
+    EventHandler.prototype = {
+        // event accepts: 'click' or 'click.scope'
+        bind: function(event, listener, target) {
+            var type = event.split('.')[0];
+            target.addEventListener(type, listener, false);
+            this.events[event] = {
+                type: type,
+                listener: listener
+            }
+        },
+        unbind: function(event, target) {
+            if (event in this.events) {
+                target.removeEventListener(this.events[event].type, this.events[event].listener, false);
+                delete this.events[event];
+            }
+        }
+    }
+
+    // Object Definition
+    var Wrap = function(selector) {
+        this.selector = selector;
+        return this._setup([]);
+    }
+
+    // CONSTRUCTOR
+    Wrap.Constructor = function(param, attrs) {
+        var el = new Wrap(param);
+        return el.init(attrs);
+    };
+
+    // Core methods
+    Wrap.prototype = {
+        constructor: Wrap,
+        /**
+         * Initialize the object depending on param type
+         * [attrs] only to handle $(htmlString, {attributes})
+         */
+        init: function(attrs) {
+            // empty object
+            if (!this.selector) return this;
+            // selector === string
+            if (typeof this.selector === 'string') {
+                // if looks like markup, try to create an element
+                if (this.selector[0] === '<') {
+                    var elem = this._setup([this._create(this.selector)])
+                    return attrs ? elem.attr(attrs) : elem;
+                } else
+                    return this._setup(arrayFrom(document.querySelectorAll(this.selector)))
+            }
+            // selector === DOMElement
+            if (this.selector.nodeType)
+                return this._setup([this.selector])
+            else // shorthand for DOMReady
+                if (typeof this.selector === 'function')
+                    return this._setup([document]).ready(this.selector)
+            // Array like objects (e.g. NodeList/HTMLCollection)
+            return this._setup(arrayFrom(this.selector))
+        },
+        /**
+         * Creates a DOM element from a string
+         * Strictly supports the form: '<tag>' or '<tag/>'
+         */
+        _create: function(str) {
+            var nodeName = str.substr(str.indexOf('<') + 1, str.indexOf('>') - 1).replace('/', '')
+            return document.createElement(nodeName);
+        },
+        /** setup properties and array to element set */
+        _setup: function(elements) {
+            var i = 0;
+            for (; i < elements.length; i++) delete this[i]; // clean up old set
+            this.elements = elements;
+            this.length = elements.length;
+            for (i = 0; i < elements.length; i++) this[i] = elements[i] // new set
+            return this;
+        },
+        _first: function(cb, ret) {
+            var f = this.elements[0];
+            return f ? (cb ? cb.call(this, f) : f) : ret;
+        },
+        /** Common function for class manipulation  */
+        _classes: function(method, classname) {
+            var cls = classname.split(' ');
+            if (cls.length > 1) {
+                cls.forEach(this._classes.bind(this, method))
+            } else {
+                if (method === 'contains') {
+                    var elem = this._first();
+                    return elem ? elem.classList.contains(classname) : false;
+                }
+                return (classname === '') ? this : this.each(function(i, item) {
+                    item.classList[method](classname);
+                })
+            }
+        },
+        /**
+         * Multi purpose function to set or get a (key, value)
+         * If no value, works as a getter for the given key
+         * key can be an object in the form {key: value, ...}
+         */
+        _access: function(key, value, fn) {
+            if (typeof key === 'object') {
+                for (var k in key) {
+                    this._access(k, key[k], fn);
+                }
+            } else if (value === undefined) {
+                return this._first(function(elem) {
+                    return fn(elem, key);
+                });
+            }
+            return this.each(function(i, item) {
+                fn(item, key, value);
+            });
+        },
+        each: function(fn, arr) {
+            arr = arr ? arr : this.elements;
+            for (var i = 0; i < arr.length; i++) {
+                if (fn.call(arr[i], i, arr[i]) === false)
+                    break;
+            }
+            return this;
+        }
+    }
+
+    /** Allows to extend with new methods */
+    Wrap.extend = function(methods) {
+        Object.keys(methods).forEach(function(m) {
+            Wrap.prototype[m] = methods[m]
+        })
+    }
+
+    // DOM READY
+    Wrap.extend({
+        ready: function(fn) {
+            if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') {
+                fn();
+            } else {
+                document.addEventListener('DOMContentLoaded', fn);
+            }
+            return this;
+        }
+    })
+    // ACCESS
+    Wrap.extend({
+        /** Get or set a css value */
+        css: function(key, value) {
+            var getStyle = function(e, k) { return e.style[k] || getComputedStyle(e)[k]; };
+            return this._access(key, value, function(item, k, val) {
+                var unit = (typeof val === 'number') ? 'px' : '';
+                return val === undefined ? getStyle(item, k) : (item.style[k] = val + unit);
+            })
+        },
+        /** Get an attribute or set it */
+        attr: function(key, value) {
+            return this._access(key, value, function(item, k, val) {
+                return val === undefined ? item.getAttribute(k) : item.setAttribute(k, val)
+            })
+        },
+        /** Get a property or set it */
+        prop: function(key, value) {
+            return this._access(key, value, function(item, k, val) {
+                return val === undefined ? item[k] : (item[k] = val);
+            })
+        },
+        position: function() {
+            return this._first(function(elem) {
+                return { left: elem.offsetLeft, top: elem.offsetTop }
+            });
+        },
+        scrollTop: function(value) {
+            return this._access('scrollTop', value, function(item, k, val) {
+                return val === undefined ? item[k] : (item[k] = val);
+            })
+        },
+        outerHeight: function(includeMargin) {
+            return this._first(function(elem) {
+                var style = getComputedStyle(elem);
+                var margins = includeMargin ? (parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10)) : 0;
+                return elem.offsetHeight + margins;
+            });
+        },
+        /**
+         * Find the position of the first element in the set
+         * relative to its sibling elements.
+         */
+        index: function() {
+            return this._first(function(el) {
+                return arrayFrom(el.parentNode.children).indexOf(el)
+            }, -1);
+        }
+    })
+    // LOOKUP
+    Wrap.extend({
+        children: function(selector) {
+            var childs = [];
+            this.each(function(i, item) {
+                childs = childs.concat(map(item.children, function(item) {
+                    return item
+                }))
+            })
+            return Wrap.Constructor(childs).filter(selector);
+        },
+        siblings: function() {
+            var sibs = []
+            this.each(function(i, item) {
+                sibs = sibs.concat(filter(item.parentNode.children, function(child) {
+                    return child !== item;
+                }))
+            })
+            return Wrap.Constructor(sibs)
+        },
+        /** Return the parent of each element in the current set */
+        parent: function() {
+            var par = map(this.elements, function(item) {
+                return item.parentNode;
+            })
+            return Wrap.Constructor(par)
+        },
+        /** Return ALL parents of each element in the current set */
+        parents: function(selector) {
+            var par = [];
+            this.each(function(i, item) {
+                for (var p = item.parentElement; p; p = p.parentElement)
+                    par.push(p);
+            })
+            return Wrap.Constructor(par).filter(selector)
+        },
+        /**
+         * Get the descendants of each element in the set, filtered by a selector
+         * Selector can't start with ">" (:scope not supported on IE).
+         */
+        find: function(selector) {
+            var found = []
+            this.each(function(i, item) {
+                found = found.concat(map(item.querySelectorAll( /*':scope ' + */ selector), function(fitem) {
+                    return fitem
+                }))
+            })
+            return Wrap.Constructor(found)
+        },
+        /** filter the actual set based on given selector */
+        filter: function(selector) {
+            if (!selector) return this;
+            var res = filter(this.elements, function(item) {
+                return matches(item, selector)
+            })
+            return Wrap.Constructor(res)
+        },
+        /** Works only with a string selector */
+        is: function(selector) {
+            var found = false;
+            this.each(function(i, item) {
+                return !(found = matches(item, selector))
+            })
+            return found;
+        }
+    });
+    // ELEMENTS
+    Wrap.extend({
+        /**
+         * append current set to given node
+         * expects a dom node or set
+         * if element is a set, prepends only the first
+         */
+        appendTo: function(elem) {
+            elem = elem.nodeType ? elem : elem._first()
+            return this.each(function(i, item) {
+                elem.appendChild(item);
+            })
+        },
+        /**
+         * Append a domNode to each element in the set
+         * if element is a set, append only the first
+         */
+        append: function(elem) {
+            elem = elem.nodeType ? elem : elem._first()
+            return this.each(function(i, item) {
+                item.appendChild(elem);
+            })
+        },
+        /**
+         * Insert the current set of elements after the element
+         * that matches the given selector in param
+         */
+        insertAfter: function(selector) {
+            var target = document.querySelector(selector);
+            return this.each(function(i, item) {
+                target.parentNode.insertBefore(item, target.nextSibling);
+            })
+        },
+        /**
+         * Clones all element in the set
+         * returns a new set with the cloned elements
+         */
+        clone: function() {
+            var clones = map(this.elements, function(item) {
+                return item.cloneNode(true)
+            })
+            return Wrap.Constructor(clones);
+        },
+        /** Remove all node in the set from DOM. */
+        remove: function() {
+            this.each(function(i, item) {
+                delete item.events;
+                delete item.data;
+                if (item.parentNode) item.parentNode.removeChild(item);
+            })
+            this._setup([])
+        }
+    })
+    // DATASETS
+    Wrap.extend({
+        /**
+         * Expected key in camelCase format
+         * if value provided save data into element set
+         * if not, return data for the first element
+         */
+        data: function(key, value) {
+            var hasJSON = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+                dataAttr = 'data-' + key.replace(/[A-Z]/g, '-$&').toLowerCase();
+            if (value === undefined) {
+                return this._first(function(el) {
+                    if (el.data && el.data[key])
+                        return el.data[key];
+                    else {
+                        var data = el.getAttribute(dataAttr)
+                        if (data === 'true') return true;
+                        if (data === 'false') return false;
+                        if (data === +data + '') return +data;
+                        if (hasJSON.test(data)) return JSON.parse(data);
+                        return data;
+                    }
+                });
+            } else {
+                return this.each(function(i, item) {
+                    item.data = item.data || {};
+                    item.data[key] = value;
+                });
+            }
+        }
+    })
+    // EVENTS
+    Wrap.extend({
+        trigger: function(type) {
+            type = type.split('.')[0]; // ignore namespace
+            var event = document.createEvent('HTMLEvents');
+            event.initEvent(type, true, false);
+            return this.each(function(i, item) {
+                item.dispatchEvent(event);
+            })
+        },
+        blur: function() {
+            return this.trigger('blur')
+        },
+        focus: function() {
+            return this.trigger('focus')
+        },
+        on: function(event, callback) {
+            return this.each(function(i, item) {
+                if (!item.events) item.events = new EventHandler();
+                event.split(' ').forEach(function(ev) {
+                    item.events.bind(ev, callback, item);
+                })
+            })
+        },
+        off: function(event) {
+            return this.each(function(i, item) {
+                if (item.events) {
+                    item.events.unbind(event, item);
+                    delete item.events;
+                }
+            })
+        }
+    })
+    // CLASSES
+    Wrap.extend({
+        toggleClass: function(classname) {
+            return this._classes('toggle', classname);
+        },
+        addClass: function(classname) {
+            return this._classes('add', classname);
+        },
+        removeClass: function(classname) {
+            return this._classes('remove', classname);
+        },
+        hasClass: function(classname) {
+            return this._classes('contains', classname);
+        }
+    })
+
+    return Wrap.Constructor
+
+}));

+ 2 - 0
src/app/index.ts

@@ -0,0 +1,2 @@
+export * from './app.component';
+export * from './app.module';

+ 1 - 0
src/app/layout/footer/footer.component.html

@@ -0,0 +1 @@
+<div class="ml-2 mt-2">&copy; 2019 - {{ settings.getAppSetting('name') }}</div>

+ 0 - 0
src/app/layout/footer/footer.component.scss


+ 17 - 0
src/app/layout/footer/footer.component.ts

@@ -0,0 +1,17 @@
+import { Component, OnInit } from '@angular/core';
+import { SettingsService } from '../../core/settings/settings.service';
+
+@Component({
+    selector: '[app-footer]',
+    templateUrl: './footer.component.html',
+    styleUrls: ['./footer.component.scss']
+})
+export class FooterComponent implements OnInit {
+
+    constructor(public settings: SettingsService) { }
+
+    ngOnInit() {
+
+    }
+
+}

+ 126 - 0
src/app/layout/header/header.component.h.html

@@ -0,0 +1,126 @@
+<!-- START Top Navbar-->
+<nav class="navbar topnavbar navbar-expand-lg navbar-light" role="navigation">
+    <!-- START navbar header-->
+    <div class="navbar-header">
+        <a class="navbar-brand" href="#/">
+            <div class="brand-logo">
+                <img class="img-fluid" src="assets/img/logo.png" alt="App Logo" />
+            </div>
+            <div class="brand-logo-collapsed">
+                <img class="img-fluid" src="assets/img/logo-single.png" alt="App Logo" />
+            </div>
+        </a>
+       <button class="navbar-toggler" type="button" (click)="navCollapsed = !navCollapsed">
+          <span class="navbar-toggler-icon"></span>
+       </button>
+    </div>
+    <!-- END navbar header-->
+    <!-- START Nav wrapper-->
+    <div class="navbar-collapse collapse" [collapse]="navCollapsed">
+        <!-- Navbar Menu -->
+        <ul class="nav navbar-nav mr-auto flex-column flex-lg-row">
+            <li class="nav-item" *ngFor="let item of menuItems" [ngClass]="{'dropdown': item.submenu}" dropdown>
+                <a class="nav-link" *ngIf="!item.heading && !item.submenu" [routerLink]="item.link" [title]="item.text">
+                    <span>{{(item.translate | translate) || item.text}}</span>
+                </a>
+                <a class="nav-link dropdown-toggle dropdown-toggle-nocaret" dropdownToggle *ngIf="item.submenu">
+                    <span>{{(item.translate | translate) || item.text}}</span>
+                </a>
+                <!-- START Dropdown menu-->
+                <div *dropdownMenu class="dropdown-menu animated fadeInUp">
+                    <a class="dropdown-item" *ngFor="let subitem of item.submenu" [routerLink]="subitem.link" [title]="subitem.text" >
+                        <span>{{(subitem.translate | translate) || subitem.text}}</span>
+                    </a>
+                </div>
+            </li>
+        </ul>
+        <!-- End Navbar Menu-->
+        <!-- START Right Navbar-->
+        <ul class="navbar-nav flex-row">
+            <!-- START lock screen-->
+            <li class="nav-item">
+                <a class="nav-link" title="Lock screen" [routerLink]="'/lock'">
+                    <em class="icon-lock"></em>
+                </a>
+            </li>
+            <!-- END lock screen-->
+            <!-- Fullscreen (only desktops)-->
+            <li class="nav-item d-none d-md-block">
+                <a class="nav-link" #fsbutton (click)="toggleFullScreen($event)">
+                    <em class="fa fa-expand"></em>
+                </a>
+            </li>
+            <!-- START Alert menu-->
+            <li class="nav-item dropdown dropdown-list" dropdown>
+                <a class="nav-link dropdown-toggle dropdown-toggle-nocaret" dropdownToggle>
+                    <em class="icon-bell"></em>
+                    <span class="badge badge-danger">11</span>
+                </a>
+                <!-- START Dropdown menu-->
+                <div *dropdownMenu class="dropdown-menu dropdown-menu-right animated flipInX">
+                    <div class="dropdown-item">
+                        <!-- START list group-->
+                        <div class="list-group">
+                           <!-- list item-->
+                           <div class="list-group-item list-group-item-action">
+                              <div class="media">
+                                 <div class="align-self-start mr-2">
+                                    <em class="fab fa-twitter fa-2x text-info"></em>
+                                 </div>
+                                 <div class="media-body">
+                                    <p class="m-0">New followers</p>
+                                    <p class="m-0 text-muted text-sm">1 new follower</p>
+                                 </div>
+                              </div>
+                           </div>
+                           <!-- list item-->
+                           <div class="list-group-item list-group-item-action">
+                              <div class="media">
+                                 <div class="align-self-start mr-2">
+                                    <em class="fa fa-envelope fa-2x text-warning"></em>
+                                 </div>
+                                 <div class="media-body">
+                                    <p class="m-0">New e-mails</p>
+                                    <p class="m-0 text-muted text-sm">You have 10 new emails</p>
+                                 </div>
+                              </div>
+                           </div>
+                           <!-- list item-->
+                           <div class="list-group-item list-group-item-action">
+                              <div class="media">
+                                 <div class="align-self-start mr-2">
+                                    <em class="fa fa-tasks fa-2x text-success"></em>
+                                 </div>
+                                 <div class="media-body">
+                                    <p class="m-0">Pending Tasks</p>
+                                    <p class="m-0 text-muted text-sm">11 pending task</p>
+                                 </div>
+                              </div>
+                           </div>
+                           <!-- last list item-->
+                           <div class="list-group-item list-group-item-action">
+                              <span class="d-flex align-items-center">
+                                 <span class="text-sm">More notifications</span>
+                                 <span class="badge badge-danger ml-auto">14</span>
+                              </span>
+                           </div>
+                        </div>
+                        <!-- END list group-->
+                    </div>
+                </div>
+                <!-- END Dropdown menu-->
+            </li>
+            <!-- END Alert menu-->
+            <!-- START Offsidebar button-->
+            <li class="nav-item">
+                <a class="nav-link" (click)="toggleOffsidebar(); $event.stopPropagation()">
+                    <em class="icon-notebook"></em>
+                </a>
+            </li>
+            <!-- END Offsidebar menu-->
+        </ul>
+        <!-- END Right Navbar-->
+    </div>
+    <!-- END Nav wrapper-->
+</nav>
+<!-- END Top Navbar-->

+ 131 - 0
src/app/layout/header/header.component.html

@@ -0,0 +1,131 @@
+<!-- START Top Navbar-->
+<nav class="navbar topnavbar" role="navigation">
+    <!-- START navbar header-->
+    <div class="navbar-header">
+        <a class="navbar-brand" href="#/">
+            <div class="brand-logo">
+                <img class="img-fluid" src="assets/img/logo.png" alt="App Logo" />
+            </div>
+            <div class="brand-logo-collapsed">
+                <img class="img-fluid" src="assets/img/logo-single.png" alt="App Logo" />
+            </div>
+        </a>
+    </div>
+    <!-- END navbar header-->
+    <!-- START Left navbar-->
+    <ul class="navbar-nav mr-auto flex-row">
+        <li class="nav-item">
+            <!-- Button used to collapse the left sidebar. Only visible on tablet and desktops-->
+            <a class="nav-link d-none d-md-block d-lg-block d-xl-block" trigger-resize="" (click)="toggleCollapsedSideabar()" *ngIf="!isCollapsedText()">
+                <em class="fas fa-bars"></em>
+            </a>
+            <!-- Button to show/hide the sidebar on mobile. Visible on mobile only.-->
+            <a class="nav-link sidebar-toggle d-md-none" (click)="settings.toggleLayoutSetting('asideToggled'); $event.stopPropagation()">
+                <em class="fas fa-bars"></em>
+            </a>
+        </li>
+        <!-- START User avatar toggle-->
+        <li class="nav-item d-none d-md-block">
+            <!-- Button used to collapse the left sidebar. Only visible on tablet and desktops-->
+            <a  class="nav-link" (click)="toggleUserBlock($event)">
+                <em class="icon-user"></em>
+            </a>
+        </li>
+        <!-- END User avatar toggle-->
+        <!-- START lock screen
+        <li class="nav-item d-none d-md-block">
+            <a class="nav-link"  title="Lock screen" [routerLink]="'/lock'">
+                <em class="icon-lock"></em>
+            </a>
+        </li>
+        -->
+        <!-- END lock screen-->
+    </ul>
+    <!-- END Left navbar-->
+    <!-- START Right Navbar-->
+    <ul class="navbar-nav flex-row">
+        <!-- Fullscreen (only desktops)-->
+        <li class="nav-item d-none d-md-block">
+            <a class="nav-link" #fsbutton (click)="toggleFullScreen($event)">
+                <em class="fa fa-expand"></em>
+            </a>
+        </li>
+        <!-- START Alert menu-->
+        <li class="nav-item dropdown dropdown-list" dropdown>
+            <a class="nav-link dropdown-toggle dropdown-toggle-nocaret" dropdownToggle>
+                <em class="icon-bell"></em>
+                <span class="badge badge-danger">11</span>
+            </a>
+            <!-- START Dropdown menu-->
+            <div *dropdownMenu class="dropdown-menu dropdown-menu-right animated flipInX">
+                <div class="dropdown-item">
+                    <!-- START list group-->
+                    <div class="list-group">
+                       <!-- list item-->
+                       <div class="list-group-item list-group-item-action">
+                          <div class="media">
+                             <div class="align-self-start mr-2">
+                                <em class="fab fa-twitter fa-2x text-info"></em>
+                             </div>
+                             <div class="media-body">
+                                <p class="m-0">New followers</p>
+                                <p class="m-0 text-muted text-sm">1 new follower</p>
+                             </div>
+                          </div>
+                       </div>
+                       <!-- list item-->
+                       <div class="list-group-item list-group-item-action">
+                          <div class="media">
+                             <div class="align-self-start mr-2">
+                                <em class="fa fa-envelope fa-2x text-warning"></em>
+                             </div>
+                             <div class="media-body">
+                                <p class="m-0">New e-mails</p>
+                                <p class="m-0 text-muted text-sm">You have 10 new emails</p>
+                             </div>
+                          </div>
+                       </div>
+                       <!-- list item-->
+                       <div class="list-group-item list-group-item-action">
+                          <div class="media">
+                             <div class="align-self-start mr-2">
+                                <em class="fa fa-tasks fa-2x text-success"></em>
+                             </div>
+                             <div class="media-body">
+                                <p class="m-0">Pending Tasks</p>
+                                <p class="m-0 text-muted text-sm">11 pending task</p>
+                             </div>
+                          </div>
+                       </div>
+                       <!-- last list item-->
+                       <div class="list-group-item list-group-item-action">
+                          <span class="d-flex align-items-center">
+                             <span class="text-sm">More notifications</span>
+                             <span class="badge badge-danger ml-auto">14</span>
+                          </span>
+                       </div>
+                    </div>
+                    <!-- END list group-->
+                </div>
+            </div>
+            <!-- END Dropdown menu-->
+        </li>
+        <!-- END Alert menu-->
+        <!-- START Offsidebar button-->
+        <li class="nav-item">
+            <a class="nav-link" (click)="toggleOffsidebar(); $event.stopPropagation()">
+                <em class="icon-notebook"></em>
+            </a>
+        </li>
+        <!-- END Offsidebar menu-->
+        <li class="nav-item d-none d-md-block">
+            <a class="nav-link" #fsbutton (click)="logout()">
+                <em class="icon-logout"></em>
+            </a>
+    </li>
+
+    </ul>
+    <!-- END Right Navbar-->
+
+</nav>
+<!-- END Top Navbar-->

+ 0 - 0
src/app/layout/header/header.component.scss


+ 73 - 0
src/app/layout/header/header.component.ts

@@ -0,0 +1,73 @@
+import { Component, OnInit, ViewChild } from '@angular/core';
+const screenfull = require('screenfull');
+
+import { UserblockService } from '../sidebar/userblock/userblock.service';
+import { SettingsService } from '../../core/settings/settings.service';
+import { MenuService } from '../../core/menu/menu.service';
+import { AjaxService } from '../../core/ajax/ajax.service';
+import { MsgService } from '../../core/msg/msg.service';
+
+@Component({
+    selector: 'app-header',
+    templateUrl: './header.component.html',
+    styleUrls: ['./header.component.scss']
+})
+export class HeaderComponent implements OnInit {
+
+    navCollapsed = true; // for horizontal layout
+    menuItems = []; // for horizontal layout
+
+    @ViewChild('fsbutton', {static: true}) fsbutton;  // the fullscreen button
+
+    constructor(public menu: MenuService, public userblockService: UserblockService, public settings: SettingsService) {
+        this.menuItems = menu.getMenu().slice(0, 4); // for horizontal layout
+
+    }
+
+    ngOnInit() {
+        var ua = window.navigator.userAgent;
+        if (ua.indexOf("MSIE ") > 0 || !!ua.match(/Trident.*rv\:11\./)) { // Not supported under IE
+            this.fsbutton.nativeElement.style.display = 'none';
+        }
+
+        // Switch fullscreen icon indicator
+        const el = this.fsbutton.nativeElement.firstElementChild;
+        screenfull.on('change', () => {
+            if (el)
+                el.className = screenfull.isFullscreen ? 'fa fa-compress' : 'fa fa-expand';
+        });
+    }
+
+    toggleUserBlock(event) {
+        event.preventDefault();
+        this.userblockService.toggleVisibility();
+    }
+
+
+    toggleOffsidebar() {
+        this.settings.toggleLayoutSetting('offsidebarOpen');
+    }
+
+    toggleCollapsedSideabar() {
+        this.settings.toggleLayoutSetting('isCollapsed');
+    }
+
+    isCollapsedText() {
+        return this.settings.getLayoutSetting('isCollapsedText');
+    }
+
+    toggleFullScreen(event) {
+        if (screenfull.enabled) {
+            screenfull.toggle();
+        }
+    }
+
+    //退出系统
+    logout(){
+        MsgService.confirm('确定要退出系统吗?', () => {
+            AjaxService.request("frame/optr/logout.htm",{},  () => {
+                window.location.href = "./assets/login/index.html";
+            });
+        });
+    }
+}

+ 15 - 0
src/app/layout/layout.component.h.html

@@ -0,0 +1,15 @@
+<div class="wrapper">
+    <!-- top navbar-->
+    <app-header class="topnavbar-wrapper"></app-header>
+    <!-- offsidebar-->
+    <app-offsidebar class="offsidebar"></app-offsidebar>
+    <!-- Main section-->
+    <section class="section-container">
+        <!-- Page content-->
+        <div class="content-wrapper">
+            <router-outlet></router-outlet>
+        </div>
+    </section>
+    <!-- Page footer-->
+    <footer class="footer-container" app-footer></footer>
+</div>

+ 17 - 0
src/app/layout/layout.component.html

@@ -0,0 +1,17 @@
+<div class="wrapper">
+    <!-- top navbar-->
+    <app-header class="topnavbar-wrapper"></app-header>
+    <!-- sidebar-->
+    <app-sidebar class="aside-container"></app-sidebar>
+    <!-- offsidebar-->
+    <app-offsidebar class="offsidebar"></app-offsidebar>
+    <!-- Main section-->
+    <section class="section-container">
+        <!-- Page content-->
+        <div class="content-wrapper">
+            <router-outlet></router-outlet>
+        </div>
+    </section>
+    <!-- Page footer-->
+    <footer class="footer-container" app-footer></footer>
+</div>

+ 0 - 0
src/app/layout/layout.component.scss


+ 15 - 0
src/app/layout/layout.component.ts

@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+    selector: 'app-layout',
+    templateUrl: './layout.component.html',
+    styleUrls: ['./layout.component.scss']
+})
+export class LayoutComponent implements OnInit {
+
+    constructor() { }
+
+    ngOnInit() {
+    }
+
+}

+ 44 - 0
src/app/layout/layout.module.ts

@@ -0,0 +1,44 @@
+import { NgModule } from '@angular/core';
+
+import { LayoutComponent } from './layout.component';
+import { SidebarComponent } from './sidebar/sidebar.component';
+import { HeaderComponent } from './header/header.component';
+import { OffsidebarComponent } from './offsidebar/offsidebar.component';
+import { UserblockComponent } from './sidebar/userblock/userblock.component';
+import { UserblockService } from './sidebar/userblock/userblock.service';
+import { FooterComponent } from './footer/footer.component';
+
+import { SharedModule } from '../shared/shared.module';
+import {FrameOptrEditComponent} from '../routes/frame/optr/frame-optr-edit/frame-optr-edit.component';
+import {FrameOptrPasswordComponent} from '../routes/frame/optr/frame-optr-password/frame-optr-password.component';
+import {FrameThreadRunningComponent} from '../routes/frame/thread/frame-thread-running/frame-thread-running.component';
+
+@NgModule({
+    imports: [
+        SharedModule
+    ],
+    providers: [
+        UserblockService
+    ],
+  entryComponents: [FrameOptrEditComponent, FrameOptrPasswordComponent, FrameThreadRunningComponent],
+    declarations: [
+        LayoutComponent,
+        SidebarComponent,
+        UserblockComponent,
+        HeaderComponent,
+        OffsidebarComponent,
+        FooterComponent,
+        FrameOptrEditComponent,
+        FrameOptrPasswordComponent,
+        FrameThreadRunningComponent
+    ],
+    exports: [
+        LayoutComponent,
+        SidebarComponent,
+        UserblockComponent,
+        HeaderComponent,
+        OffsidebarComponent,
+        FooterComponent
+    ]
+})
+export class LayoutModule { }

+ 350 - 0
src/app/layout/offsidebar/offsidebar.component.html

@@ -0,0 +1,350 @@
+<tabset [justified]="true">
+    <tab>
+        <ng-template tabHeading>
+            <em class="icon-equalizer fa-lg"></em>
+        </ng-template>
+        <h3 class="text-center text-thin mt-4" [innerHTML]="'调色板'"></h3>
+        <div class="p-2">
+            <h4 class="text-muted text-thin">Themes</h4>
+            <div class="row row-flush mb-2">
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="A" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-info"></span>
+                            <span class="color bg-info-light"></span>
+                            </span>
+                            <span class="color bg-white"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="B" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-green"></span>
+                            <span class="color bg-green-light"></span>
+                            </span>
+                            <span class="color bg-white"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="C" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-purple"></span>
+                            <span class="color bg-purple-light"></span>
+                            </span>
+                            <span class="color bg-white"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="D" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-danger"></span>
+                            <span class="color bg-danger-light"></span>
+                            </span>
+                            <span class="color bg-white"></span>
+                        </label>
+                    </div>
+                </div>
+            </div>
+            <div class="row row-flush mb-2">
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="E" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-info-dark"></span>
+                            <span class="color bg-info"></span>
+                            </span>
+                            <span class="color bg-gray-dark"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="F" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-green-dark"></span>
+                            <span class="color bg-green"></span>
+                            </span>
+                            <span class="color bg-gray-dark"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="G" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-purple-dark"></span>
+                            <span class="color bg-purple"></span>
+                            </span>
+                            <span class="color bg-gray-dark"></span>
+                        </label>
+                    </div>
+                </div>
+                <div class="col mb-2">
+                    <div class="setting-color">
+                        <label>
+                            <input type="radio" name="setting-theme" [(ngModel)]="currentTheme" (ngModelChange)="setTheme()" value="H" />
+                            <span class="icon-check"></span>
+                            <span class="split">
+                            <span class="color bg-danger-dark"></span>
+                            <span class="color bg-danger"></span>
+                            </span>
+                            <span class="color bg-gray-dark"></span>
+                        </label>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="p-2">
+            <h4 class="text-muted text-thin">Layout</h4>
+            <div class="clearfix">
+                <p class="float-left">Fixed</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('isFixed')"
+                            (ngModelChange)="settings.setLayoutSetting('isFixed', $event)" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <div class="clearfix">
+                <p class="float-left">Boxed</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('isBoxed')"
+                            (ngModelChange)="settings.setLayoutSetting('isBoxed', $event)" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <!--
+    <div class="clearfix">
+      <p class="float-left">RTL</p>
+      <div class="float-right">
+         <label class="switch">
+            <input type="checkbox" [(ngModel)]="layoutRTL"/>
+            <span></span>
+         </label>
+      </div>
+    </div>
+    -->
+        </div>
+        <div class="p-2" *ngIf="!settings.getLayoutSetting('horizontal')">
+            <h4 class="text-muted text-thin">Aside</h4>
+            <div class="clearfix">
+                <p class="float-left">Collapsed</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('isCollapsed')"
+                            (ngModelChange)="settings.setLayoutSetting('isCollapsed', $event)"
+                            [disabled]="settings.getLayoutSetting('isCollapsedText')" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <div class="clearfix">
+                <p class="float-left">Collapsed Text</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('isCollapsedText')"
+                            (ngModelChange)="settings.setLayoutSetting('isCollapsedText', $event)"
+                            [disabled]="settings.getLayoutSetting('isCollapsed')" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <div class="clearfix">
+                <p class="float-left">Float</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('isFloat')"
+                            (ngModelChange)="settings.setLayoutSetting('isFloat', $event)" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <div class="clearfix">
+                <p class="float-left">Hover</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('asideHover')"
+                            (ngModelChange)="settings.setLayoutSetting('asideHover', $event)" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+            <div class="clearfix">
+                <p class="float-left">Show Scrollbar</p>
+                <div class="float-right">
+                    <label class="switch">
+                        <input type="checkbox"
+                            [ngModel]="settings.getLayoutSetting('asideScrollbar')"
+                            (ngModelChange)="settings.setLayoutSetting('asideScrollbar', $event)" />
+                        <span></span>
+                    </label>
+                </div>
+            </div>
+        </div>
+    </tab>
+    <tab>
+        <ng-template tabHeading>
+            <em class="icon-user fa-lg"></em>
+        </ng-template>
+        <h3 class="text-center text-thin mt-4">Connections</h3>
+        <div class="list-group">
+            <!-- START list title-->
+            <div class="list-group-item border-0">
+                <small class="text-muted">ONLINE</small>
+            </div>
+            <!-- END list title-->
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/05.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Juan Sims</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-success circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/06.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Maureen Jenkins</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-success circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/07.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Billie Dunn</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-danger circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/08.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Tomothy Roberts</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-warning circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+            <!-- START list title-->
+            <div class="list-group-item border-0">
+                <small class="text-muted">OFFLINE</small>
+            </div>
+            <!-- END list title-->
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/09.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Lawrence Robinson</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-warning circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+            <div class="list-group-item list-group-item-action border-0">
+                <div class="media">
+                    <img class="align-self-center mr-3 rounded-circle thumb48" src="assets/img/user/10.jpg" alt="Image">
+                    <div class="media-body text-truncate">
+                        <a href="#">
+                                    <strong>Tyrone Owens</strong>
+                                 </a>
+                        <br>
+                        <small class="text-muted">Designeer</small>
+                    </div>
+                    <div class="ml-auto">
+                        <span class="circle bg-warning circle-lg"></span>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="px-3 py-4 text-center">
+            <!-- Optional link to list more users-->
+            <a class="btn btn-purple btn-sm" href="#" title="See more contacts">
+                           <strong>Load more..</strong>
+                        </a>
+        </div>
+        <!-- Extra items-->
+        <div class="px-3 py-2">
+            <p>
+                <small class="text-muted">Tasks completion</small>
+            </p>
+            <div class="progress progress-xs m-0">
+                <div class="progress-bar bg-success" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100" style="width: 80%;">
+                    <span class="sr-only">80% Complete</span>
+                </div>
+            </div>
+        </div>
+        <div class="px-3 py-2">
+            <p>
+                <small class="text-muted">Upload quota</small>
+            </p>
+            <div class="progress progress-xs m-0">
+                <div class="progress-bar bg-warning" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 40%;">
+                    <span class="sr-only">40% Complete</span>
+                </div>
+            </div>
+        </div>
+    </tab>
+</tabset>

+ 0 - 0
src/app/layout/offsidebar/offsidebar.component.scss


+ 49 - 0
src/app/layout/offsidebar/offsidebar.component.ts

@@ -0,0 +1,49 @@
+import {Component, OnInit, OnDestroy, ElementRef} from '@angular/core';
+
+import {SettingsService} from '../../core/settings/settings.service';
+import {ThemesService} from '../../core/themes/themes.service';
+import {CookieService} from 'ngx-cookie-service';
+
+@Component({
+  selector: 'app-offsidebar',
+  templateUrl: './offsidebar.component.html',
+  styleUrls: ['./offsidebar.component.scss']
+})
+export class OffsidebarComponent implements OnInit, OnDestroy {
+
+  currentTheme: any;
+
+  constructor(public settings: SettingsService, public themes: ThemesService, public elem: ElementRef, public cookie: CookieService) {
+    if (cookie.get('frame.layout.theme') === undefined) {
+      this.currentTheme = themes.getDefaultTheme();
+    } else {
+      this.currentTheme = cookie.get('frame.layout.theme');
+      this.themes.setTheme(this.currentTheme);
+    }
+  }
+
+  ngOnInit() {
+    this.anyClickClose();
+  }
+
+  setTheme() {
+    this.cookie.set('frame.layout.theme', this.currentTheme);
+    this.themes.setTheme(this.currentTheme);
+  }
+
+
+  anyClickClose() {
+    document.addEventListener('click', this.checkCloseOffsidebar.bind(this), false);
+  }
+
+  checkCloseOffsidebar(e) {
+    const contains = (this.elem.nativeElement !== e.target && this.elem.nativeElement.contains(e.target));
+    if (!contains) {
+      this.settings.setLayoutSetting('offsidebarOpen', false);
+    }
+  }
+
+  ngOnDestroy() {
+    document.removeEventListener('click', this.checkCloseOffsidebar);
+  }
+}

+ 116 - 0
src/app/layout/sidebar/sidebar.component.html

@@ -0,0 +1,116 @@
+<!-- START Sidebar (left)-->
+<div class="aside-inner">
+    <nav class="sidebar" sidebar-anyclick-close="" [class.show-scrollbar]="settings.getLayoutSetting('asideScrollbar')">
+
+        <!-- START sidebar nav-->
+        <ul class="sidebar-nav">
+
+            <!-- START user info-->
+            <li class="has-user-block">
+                <app-userblock></app-userblock>
+            </li>`
+            <!-- END user info-->
+
+            <li *ngFor='let item of menuItems' [ngClass]="{'nav-heading': item.heading}" [routerLinkActive]="['active']">
+                <!-- menu heading -->
+                <span *ngIf="item.heading">{{item.text}}</span>
+                <!-- external links -->
+                <a href *ngIf="!item.heading && !item.submenu && item.elink" [attr.target]="item.target" [attr.href]="item.elink" title="{{item.text}}">
+                    <span class="float-right" *ngIf="item.alert" [ngClass]="item.label || 'badge badge-success'">{{item.alert}}</span>
+                    <em class="{{item.icon}}" *ngIf="item.icon"></em>
+                    <span>{{item.text}}</span>
+                </a>
+                <!-- single menu item -->
+                <a href *ngIf="!item.heading && !item.submenu && !item.elink" [routerLink]="item.link" [attr.route]="item.link" title="{{item.text}}"
+                    (click)="toggleSubmenuClick($event)" (mouseenter)="toggleSubmenuHover($event)">
+                    <span class="float-right" *ngIf="item.alert" [ngClass]="item.label || 'badge badge-success'">{{item.alert}}</span>
+                    <em class="{{item.icon}}" *ngIf="item.icon"></em>
+                    <span>{{item.text}}</span>
+                </a>
+                <!-- has submenu -->
+                <a href *ngIf="!item.heading && item.submenu" title="{{item.text}}"
+                    (click)="toggleSubmenuClick($event)" (mouseenter)="toggleSubmenuHover($event)">
+                        <span class="float-right" *ngIf="item.alert" [ngClass]="item.label || 'badge badge-success'">{{item.alert}}</span>
+                        <em class="{{item.icon}}" *ngIf="item.icon"></em>
+                        <span>{{item.text}}</span>
+                </a>
+                <!-- SUBLEVEL -->
+                <ul *ngIf="item.submenu" class="sidebar-nav sidebar-subnav" [routerLinkActive]="['opening']">
+                    <li class="sidebar-subnav-header">{{item.text}}</li>
+                    <li *ngFor='let subitem of item.submenu' [routerLinkActive]="['active']">
+                        <!-- sublevel: external links -->
+                        <a href *ngIf="!subitem.heading && !subitem.submenu && subitem.elink" [attr.target]="subitem.target" [attr.href]="subitem.elink" title="{{subitem.text}}">
+                            <span class="float-right" *ngIf="subitem.alert" [ngClass]="subitem.label || 'badge badge-success'">{{subitem.alert}}</span>
+                            <em class="{{subitem.icon}}" *ngIf="subitem.icon"></em>
+                            <span>{{subitem.text}}</span>
+                        </a>
+                        <!-- sublevel: single menu item  -->
+                        <a href *ngIf="!subitem.submenu && !subitem.elink" [routerLink]="subitem.link" [attr.route]="subitem.link" title="{{subitem.text}}">
+                            <span class="float-right" *ngIf="subitem.alert" [ngClass]="subitem.label || 'badge badge-success'">{{subitem.alert}}</span>
+                            <em class="{{subitem.icon}}" *ngIf="subitem.icon"></em>
+                            <span>{{subitem.text}}</span>
+                        </a>
+                        <!-- sublevel: has submenu -->
+                        <a href *ngIf="subitem.submenu" title="{{subitem.text}}"
+                            (click)="toggleSubmenuClick($event)" (mouseenter)="toggleSubmenuHover($event)">
+                                <span class="float-right" *ngIf="subitem.alert" [ngClass]="subitem.label || 'badge badge-success'">{{subitem.alert}}</span>
+                                <em class="{{subitem.icon}}" *ngIf="subitem.icon"></em>
+                                <span>{{subitem.text}}</span>
+                        </a>
+                        <!-- SUBLEVEL 2 -->
+                        <ul *ngIf="subitem.submenu" class="sidebar-nav sidebar-subnav level2" [routerLinkActive]="['opening']">
+                            <li *ngFor='let subitem2 of subitem.submenu' [routerLinkActive]="['active']">
+                                <!-- sublevel 2: single menu item  -->
+                                <a href *ngIf="!subitem2.submenu" [routerLink]="subitem2.link" [attr.route]="subitem2.link" title="{{subitem2.text}}">
+                                    <span class="float-right" *ngIf="subitem2.alert" [ngClass]="subitem2.label || 'badge badge-success'">{{subitem2.alert}}</span>
+                                    <em class="{{subitem2.icon}}" *ngIf="subitem2.icon"></em>
+                                    <span>{{subitem2.text}}</span>
+                                </a>
+                                <!-- sublevel2: has submenu -->
+                                <a href *ngIf="subitem2.submenu" title="{{subitem2.text}}"
+                                    (click)="toggleSubmenuClick($event)" (mouseenter)="toggleSubmenuHover($event)">
+                                        <span class="float-right" *ngIf="subitem2.alert" [ngClass]="subitem2.label || 'badge badge-success'">{{subitem2.alert}}</span>
+                                        <em class="{{subitem2.icon}}" *ngIf="subitem2.icon"></em>
+                                        <span>{{subitem2.text}}</span>
+                                </a>
+                                <!-- SUBLEVEL 3 -->
+                                <ul *ngIf="subitem2.submenu" class="sidebar-nav sidebar-subnav level3" [routerLinkActive]="['opening']">
+                                    <li *ngFor='let subitem3 of subitem2.submenu' [routerLinkActive]="['active']">
+                                        <!-- sublevel 2: single menu item  -->
+                                        <a href *ngIf="!subitem3.submenu" [routerLink]="subitem3.link" [attr.route]="subitem3.link" title="{{subitem3.text}}">
+                                            <span class="float-right" *ngIf="subitem3.alert" [ngClass]="subitem3.label || 'badge badge-success'">{{subitem3.alert}}</span>
+                                            <em class="{{subitem3.icon}}" *ngIf="subitem3.icon"></em>
+                                            <span>{{subitem3.text}}</span>
+                                        </a>
+                                        <!-- sublevel3: has submenu -->
+                                        <a href *ngIf="subitem3.submenu" title="{{subitem3.text}}"
+                                            (click)="toggleSubmenuClick($event)" (mouseenter)="toggleSubmenuHover($event)">
+                                                <span class="float-right" *ngIf="subitem3.alert" [ngClass]="subitem3.label || 'badge badge-success'">{{subitem3.alert}}</span>
+                                                <em class="{{subitem3.icon}}" *ngIf="subitem3.icon"></em>
+                                                <span>{{subitem3.text}}</span>
+                                        </a>
+                                        <!-- SUBLEVEL 4 -->
+                                        <ul *ngIf="subitem3.submenu" class="sidebar-nav sidebar-subnav level3" [routerLinkActive]="['opening']">
+                                            <li *ngFor='let subitem4 of subitem3.submenu' [routerLinkActive]="['active']">
+                                                <!-- sublevel 2: single menu item  -->
+                                                <a href *ngIf="!subitem4.submenu" [routerLink]="subitem4.link" [attr.route]="subitem4.link" title="{{subitem4.text}}">
+                                                    <span class="float-right" *ngIf="subitem4.alert" [ngClass]="subitem4.label || 'badge badge-success'">{{subitem4.alert}}</span>
+                                                    <em class="{{subitem4.icon}}" *ngIf="subitem4.icon"></em>
+                                                    <span>{{subitem4.text}}</span>
+                                                </a>
+                                            </li>
+                                        </ul>
+                                    </li>
+                                </ul>
+                            <li>
+                        </ul>
+                    <li>
+                </ul>
+            </li>
+
+        </ul>
+        <!-- END sidebar nav-->
+
+    </nav>
+</div>
+<!-- END Sidebar (left)-->

+ 0 - 0
src/app/layout/sidebar/sidebar.component.scss


+ 194 - 0
src/app/layout/sidebar/sidebar.component.ts

@@ -0,0 +1,194 @@
+import { Component, OnInit, Injector, OnDestroy } from '@angular/core';
+import { Router } from '@angular/router';
+declare var $: any;
+
+import { MenuService } from '../../core/menu/menu.service';
+import { SettingsService } from '../../core/settings/settings.service';
+import {BsModalService} from 'ngx-bootstrap';
+
+@Component({
+    selector: 'app-sidebar',
+    templateUrl: './sidebar.component.html',
+    styleUrls: ['./sidebar.component.scss']
+})
+export class SidebarComponent implements OnInit, OnDestroy {
+
+    menuItems: Array<any>;
+    router: Router;
+    sbclickEvent = 'click.sidebar-toggle';
+    $doc: any = null;
+
+    constructor(public menu: MenuService, public settings: SettingsService, public injector: Injector) {
+        this.menuItems = menu.getMenu();
+    }
+
+    ngOnInit() {
+
+        this.router = this.injector.get(Router);
+
+        this.router.events.subscribe((val) => {
+            // close any submenu opened when route changes
+            this.removeFloatingNav();
+            // scroll view to top
+            window.scrollTo(0, 0);
+            // close sidebar on route change
+            this.settings.setLayoutSetting('asideToggled', false);
+        });
+
+        // enable sidebar autoclose from extenal clicks
+        this.anyClickClose();
+
+    }
+
+    anyClickClose() {
+        this.$doc = $(document).on(this.sbclickEvent, (e) => {
+            if (!$(e.target).parents('.aside-container').length) {
+                this.settings.setLayoutSetting('asideToggled', false);
+            }
+        });
+    }
+
+    ngOnDestroy() {
+        if (this.$doc)
+            this.$doc.off(this.sbclickEvent);
+    }
+
+    toggleSubmenuClick(event) {
+
+        event.preventDefault();
+
+        if (!this.isSidebarCollapsed() && !this.isSidebarCollapsedText() && !this.isEnabledHover()) {
+
+            let ul = $(event.currentTarget.nextElementSibling);
+
+            // hide other submenus
+            let parentNav = ul.parents('.sidebar-subnav');
+            $('.sidebar-subnav').each((idx, el) => {
+                let $el = $(el);
+                // if element is not a parent or self ul
+                if (el !== parentNav[0] && el !== ul[0]) {
+                    this.closeMenu($el);
+                }
+            });
+
+            // abort if not UL to process
+            if (!ul.length) {
+                return;
+            }
+
+            // any child menu should start closed
+            ul.find('.sidebar-subnav').each((idx, el) => {
+                this.closeMenu($(el));
+            });
+
+            // toggle UL height
+            const ulHeight = ul.css('height')
+            if (ulHeight === 'auto' || parseInt(ulHeight, 10)) {
+                this.closeMenu(ul);
+            }
+            else {
+                // expand menu
+                ul.on('transitionend', () => {
+                    ul.css('height', 'auto').off('transitionend');
+                }).css('height', ul[0].scrollHeight);
+                // add class to manage animation
+                ul.addClass('opening');
+            }
+
+        }
+
+    }
+
+    // Close menu collapsing height
+    closeMenu(elem) {
+        elem.css('height', elem[0].scrollHeight); // set height
+        elem.css('height', 0); // and move to zero to collapse
+        elem.removeClass('opening');
+    }
+
+    toggleSubmenuHover(event) {
+        let self = this;
+        if (this.isSidebarCollapsed() || this.isSidebarCollapsedText() || this.isEnabledHover()) {
+            event.preventDefault();
+
+            this.removeFloatingNav();
+
+            let ul = $(event.currentTarget.nextElementSibling);
+            let anchor = $(event.currentTarget);
+
+            if (!ul.length) {
+                return; // if not submenu return
+            }
+
+            let $aside = $('.aside-container');
+            let $asideInner = $aside.children('.aside-inner'); // for top offset calculation
+            let $sidebar = $asideInner.children('.sidebar');
+            let mar = parseInt($asideInner.css('padding-top'), 0) + parseInt($aside.css('padding-top'), 0);
+            let itemTop = ((anchor.parent().position().top) + mar) - $sidebar.scrollTop();
+
+            let floatingNav = ul.clone().appendTo($aside);
+            let vwHeight = document.body.clientHeight;
+
+            // let itemTop = anchor.position().top || anchor.offset().top;
+
+            floatingNav
+                .addClass('nav-floating')
+
+            // each item has ~40px height
+            // multiply to force space for at least N items
+            var safeOffsetValue = (40 * 5)
+            var navHeight = floatingNav.height() + 2; // 2px border
+            var safeOffset = navHeight < safeOffsetValue ? navHeight : safeOffsetValue;
+
+            var displacement = 25;
+
+            // if not enough space to show N items, use then calculated 'safeOffset'
+            var menuTop = (vwHeight - itemTop > safeOffset) ? itemTop : (vwHeight - safeOffset - displacement);
+
+            floatingNav
+                .removeClass('opening') // necesary for demo if switched between normal//collapsed mode
+                // .addClass('nav-floating')
+                .css({
+                    position: this.settings.getLayoutSetting('isFixed') ? 'fixed' : 'absolute',
+                    top: menuTop,
+                    bottom: (floatingNav.outerHeight(true) + menuTop > vwHeight) ? (displacement+'px') : 'auto'
+                });
+
+            floatingNav
+                .on('mouseleave', () => { floatingNav.remove(); })
+                .find('a').on('click', function(e) {
+                    e.preventDefault(); // prevents page reload on click
+                    // get the exact route path to navigate
+                    let routeTo = $(this).attr('route');
+                    if (routeTo) self.router.navigate([routeTo]);
+                });
+
+            this.listenForExternalClicks();
+
+        }
+
+    }
+
+    listenForExternalClicks() {
+        let $doc = $(document).on('click.sidebar', (e) => {
+            if (!$(e.target).parents('.aside-container').length) {
+                this.removeFloatingNav();
+                $doc.off('click.sidebar');
+            }
+        });
+    }
+
+    removeFloatingNav() {
+        $('.nav-floating').remove();
+    }
+
+    isSidebarCollapsed() {
+        return this.settings.getLayoutSetting('isCollapsed');
+    }
+    isSidebarCollapsedText() {
+        return this.settings.getLayoutSetting('isCollapsedText');
+    }
+    isEnabledHover() {
+        return this.settings.getLayoutSetting('asideHover');
+    }
+}

+ 14 - 0
src/app/layout/sidebar/userblock/userblock.component.html

@@ -0,0 +1,14 @@
+<div class="item user-block" *ngIf="userBlockIsVisible()">
+    <!-- User picture-->
+    <div class="user-block-picture">
+        <div class="user-block-status">
+          <img class="img-thumbnail rounded-circle" [src]="user.optr_image ? (user.optr_image  | trustUrl): './assets/img/user/01.jpg'" alt="{{user.login_name}}" (click)="openOptr()"/>
+            <div class="circle bg-success circle-lg"></div>
+        </div>
+    </div>
+    <!-- Name and Job-->
+    <div class="user-block-info">
+        <span class="user-block-name">{{ user.optr_name}}  </span>
+        <span class="user-block-role">{{ dept?.dept_name}}</span>
+    </div>
+</div>

+ 0 - 0
src/app/layout/sidebar/userblock/userblock.component.scss


+ 42 - 0
src/app/layout/sidebar/userblock/userblock.component.ts

@@ -0,0 +1,42 @@
+import {Component, OnInit} from '@angular/core';
+
+import {UserblockService} from './userblock.service';
+import {FrameService} from '../../../core/frame/frame.service';
+import {BsModalService} from 'ngx-bootstrap';
+import {FrameOptrEditComponent} from '../../../routes/frame/optr/frame-optr-edit/frame-optr-edit.component';
+
+@Component({
+  selector: 'app-userblock',
+  templateUrl: './userblock.component.html',
+  styleUrls: ['./userblock.component.scss']
+})
+export class UserblockComponent implements OnInit {
+  user: any;
+  dept: any;
+
+  constructor(public userblockService: UserblockService, public bsService: BsModalService) {
+
+    this.user = FrameService.FrameOptr;
+    this.dept = FrameService.FrameDept;
+  }
+
+  ngOnInit() {
+  }
+
+  userBlockIsVisible() {
+    return this.userblockService.getVisibility();
+  }
+
+  openOptr() {
+    const modal = Object.assign({},  {
+      animated: true,
+      keyboard: false,
+      backdrop: true,
+      ignoreBackdropClick: true,
+      initialState: {},
+      class: 'modal-75p'
+    });
+    this.bsService.show(FrameOptrEditComponent, modal);
+
+  }
+}

+ 23 - 0
src/app/layout/sidebar/userblock/userblock.service.ts

@@ -0,0 +1,23 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class UserblockService {
+    public userBlockVisible: boolean;
+    constructor() {
+        // initially visible
+        this.userBlockVisible  = false;
+    }
+
+    getVisibility() {
+        return this.userBlockVisible;
+    }
+
+    setVisibility(stat = true) {
+        this.userBlockVisible = stat;
+    }
+
+    toggleVisibility() {
+        this.userBlockVisible = !this.userBlockVisible;
+    }
+
+}

+ 163 - 0
src/app/routes/frame/core/FrameEditComponent.ts

@@ -0,0 +1,163 @@
+import {FormGroup} from '@angular/forms';
+import {BsModalRef} from 'ngx-bootstrap';
+import {FramePageComponent} from './FramePageComponent';
+import {ElementRef, ViewChild} from '@angular/core';
+import {AjaxService} from '../../../core/ajax/ajax.service';
+import {MsgService} from '../../../core/msg/msg.service';
+import {DomSanitizer} from '@angular/platform-browser';
+import {FrameService} from '../../../core/frame/frame.service';
+
+export class FrameEditComponent {
+  // 当前模式
+  editModel = 'add';
+  frameService: any;
+  // 验证表单
+  valForm: FormGroup;
+
+  currentEntity :any;
+  bsModalRef: BsModalRef;
+  ResponseEntity: any;
+  ResponseMap: any;
+  ResponseArray: any;
+  sanitizer = AjaxService.sanitizer;
+
+
+  // 父窗口
+  framePageComponent: FramePageComponent;
+
+  // 自动焦点
+  @ViewChild('elAutoFocus', {static: false}) elAutoFocus: ElementRef;
+
+  constructor(...args) {
+    this.frameService = FrameService;
+    for (const s of args) {
+      if (s instanceof BsModalRef) {
+        this.bsModalRef = s;
+      }
+      if (s instanceof DomSanitizer) {
+        this.sanitizer = s;
+      }
+    }
+    this.currentEntity = {};
+    setTimeout(() => {
+      // console.log(this.bsModalRef);
+      this.framePageComponent = this.bsModalRef.content['FramePageComponent'];
+      if (this.bsModalRef.content['ResponseEntity'] !== undefined) {
+        this.currentEntity = Object.assign({}, this.bsModalRef.content['ResponseEntity']);
+        this.editModel = 'edit';
+      }
+      this.initDefautEntity();
+    }, 1);
+
+    setTimeout(() => {
+      if (this.elAutoFocus) {
+        this.elAutoFocus.nativeElement.focus();
+      }
+    }, 0);
+  }
+
+
+  /*************
+   * 初始化编辑对象,子类请直接覆盖此方法
+   */
+  initDefautEntity() {
+  }
+
+
+  // 关闭窗体
+  closeWindow() {
+    if (this.bsModalRef.content['closeCallback'] !== undefined) {
+      this.bsModalRef.content['closeCallback'].call(undefined, this.bsModalRef.content);
+    }
+    this.bsModalRef.hide();
+  }
+
+
+
+  /*************
+   * 提交表单前可自定义一些赋值,子类请直接覆盖此方法
+   */
+  beforeSubmitForm() {
+    return true;
+  }
+
+  // 提交表单
+  submitForm(url: string, param?: { data?: {}, successMsg?: string, confirmMsg?: string, autoClose?: boolean, RequestWithLoading?: boolean }, callback?: Function) {
+    if(!this.beforeSubmitForm()){
+      return;
+    }
+    this.valForm.markAllAsTouched();
+    if (!this.validForm()) {
+      return;
+    }
+    // 判断是否有修改
+    if (this.ResponseEntity !== undefined) {
+      let hasChange = false;
+      for (const s in this.currentEntity) {
+        if (this.currentEntity[s] !== this.ResponseEntity[s]) {
+          hasChange = true;
+          break;
+        }
+      }
+      if (!hasChange) {
+        MsgService.warnToaster('没有进行任何修改,无需提交服务器操作!');
+        return;
+      }
+    }
+
+    if (param === undefined) {
+      param = {};
+    }
+    if (param.successMsg === undefined) {
+      param.successMsg = '操作成功!';
+    }
+    if (param.autoClose === undefined) {
+      param.autoClose = true;
+    }
+    if (param.RequestWithLoading === undefined) {
+      param.RequestWithLoading = true;
+    } else {
+      param.RequestWithLoading = false;
+    }
+    const fn = function () {
+      AjaxService.request(url, Object.assign({}, this.currentEntity, param.data), (data) => {
+        MsgService.successToaster(param.successMsg);
+        // 将表单设置为未触碰
+        this.UntouchedForm();
+        // 将当前的数据保存到历史中
+        this.ResponseEntity = Object.assign({}, this.currentEntity);
+        if (callback) {
+          callback.apply(this, data);
+        }
+        if (param.autoClose === true) {
+          this.closeWindow();
+        }
+
+      }, {RequestWithLoading: param.RequestWithLoading});
+    }.bind(this);
+
+    if (param.confirmMsg) {
+      MsgService.confirm(param.confirmMsg, fn);
+    } else {
+      fn.apply(undefined);
+    }
+
+
+  }
+
+  // 将表单设置为未使用过状态
+  UntouchedForm() {
+    this.valForm.markAsUntouched();
+  }
+
+  // 判断表单是否通过了验证
+  validForm(): boolean {
+    this.valForm.markAllAsTouched();
+    return this.valForm.valid;
+  }
+
+
+  ajaxDownload(url: string, param?: any) {
+    AjaxService.ajaxDownload(url, param);
+  }
+}

+ 139 - 0
src/app/routes/frame/core/FramePageComponent.ts

@@ -0,0 +1,139 @@
+import {PagerComponent} from '../../../core/pager/pager.component';
+import {ElementRef, ViewChild} from '@angular/core';
+import {BsModalRef, BsModalService, ModalOptions} from 'ngx-bootstrap';
+import {AjaxService} from '../../../core/ajax/ajax.service';
+import {DomSanitizer} from '@angular/platform-browser';
+import {FrameThreadRunningComponent} from '../thread/frame-thread-running/frame-thread-running.component';
+import {MsgService} from '../../../core/msg/msg.service';
+import {FrameService} from '../../../core/frame/frame.service';
+import {AjaxComponent} from '../../../core/ajax/ajax.component';
+
+export class FramePageComponent {
+  // 当前在哪个步骤上
+  currentStep = 'page';
+  frameService: any;
+  // 分页组件
+  @ViewChild('pager', {static: false}) pager: PagerComponent;
+  // 分页组件
+  @ViewChild('ajax', {static: false}) ajax: AjaxComponent;
+  // 自动获得焦点
+  @ViewChild('elAutoFocus', {static: false}) elAutoFocus: ElementRef;
+
+  // 弹框服务
+  bsService: BsModalService;
+  sanitizer: DomSanitizer;
+  // 弹窗参数
+  bsOptions: ModalOptions;
+  // 弹出框类型
+  modalComponent: any;
+
+  private bsModalRef: BsModalRef;
+
+  constructor(...args) {
+    this.frameService = FrameService;
+    for (const s of args) {
+      if (s instanceof BsModalService) {
+        this.bsService = s;
+      }
+      if (s instanceof DomSanitizer) {
+        this.sanitizer = s;
+      }
+    }
+    this.bsOptions = {
+      animated: true,
+      keyboard: false,
+      backdrop: true,
+      ignoreBackdropClick: true,
+      initialState: {},
+      class: 'modal-75p'
+    };
+    if (this.bsService === undefined) {
+      this.bsService = AjaxService.injector.get<BsModalService>(BsModalService);
+    }
+    this.bsService.onHidden.subscribe((r: string) => {
+      // 防止多次订阅,产生多次刷新的问题
+      if (this.pager) {
+        this.pager.reload();
+      }
+      this.onModalClose();
+    });
+
+
+    setTimeout(() => {
+      if (this.elAutoFocus) {
+        this.elAutoFocus.nativeElement.focus();
+      }
+    }, 0);
+  }
+
+  onModalClose() {
+
+  }
+
+  // 弹框, 弹窗之前做好数据获取准备,为防止弹出窗口后报错
+  showComponentModal(component: any, param?: any, options?: any) {
+    if (param === undefined) {
+      param = {};
+    }
+    const modal = Object.assign({}, this.bsOptions, options);
+    modal.initialState = param;
+    modal.initialState['FramePageComponent'] = this;
+    // 如果需要去服务器请求数据
+    if (param['entityUrl']) {
+      AjaxService.requestEntity(param['entityUrl'], param['entityParam'], (entity) => {
+        modal.initialState['ResponseEntity'] = entity;
+        this.bsModalRef = this.bsService.show(component, modal);
+      });
+    } else if (param['mapUrl']) {
+      AjaxService.requestMap(param['mapUrl'], param['mapParam'], (map) => {
+        modal.initialState['ResponseMap'] = map;
+        this.bsModalRef = this.bsService.show(component, modal);
+      }, {RequestWithLoading: true});
+    } else if (param['arrayUrl']) {
+      AjaxService.requestArray(param['arrayUrl'], param['arrayParam'], (array) => {
+        modal.initialState['ResponseArray'] = array;
+        this.bsModalRef = this.bsService.show(component, modal);
+      }, {RequestWithLoading: true});
+    } else {
+      this.bsModalRef = this.bsService.show(component, modal);
+    }
+  }
+
+  // 弹出非预定义组件的框
+  showModal(param?: any, options?: any) {
+    this.showComponentModal(this.modalComponent, param, options);
+  }
+
+  ajaxDownload(url: string, param?: any) {
+    AjaxService.ajaxDownload(url, param);
+  }
+
+  showThreadRunning(thread: any, data?: any) {
+    MsgService.showThreadRunning(this.bsService, thread, data);
+  }
+
+
+  requestWithThread(url, data?, param?) {
+    if (param === undefined)
+      param = {};
+    if (param.confirmMsg) {
+      MsgService.confirm(param.confirmMsg, () =>{
+        AjaxService.request(url, data, (ajax) => {
+          this.showThreadRunning(ajax.entity);
+        });
+      })
+
+    }else {
+      AjaxService.request(url, data, (ajax) => {
+        this.showThreadRunning(ajax.entity);
+      });
+    }
+  }
+
+  downloadReport(param) {
+    //(click)="ajaxDownload('frame/report/download.htm', {report_name:'LayoutMaterialWrittenRoom', report_title :group?.group_name + '考场汇总-', ly_group_id:group.ly_group_id})"
+    AjaxService.requestEntity('frame/report/download/thread.htm', param, (entity) => {
+      MsgService.showThreadRunning(this.bsService, entity, {threadTitle: '报表生成中,请稍候'});
+    });
+  }
+}

+ 24 - 0
src/app/routes/frame/dept/dept.frame.module.ts

@@ -0,0 +1,24 @@
+import {NgModule} from '@angular/core';
+import {Routes, RouterModule} from '@angular/router';
+import {SharedModule} from '../../../shared/shared.module';
+import { FrameDeptDetailComponent } from './frame-dept-detail/frame-dept-detail.component';
+import { FrameDeptPageComponent } from './frame-dept-page/frame-dept-page.component';
+import { FrameDeptTreeComponent } from './frame-dept-tree/frame-dept-tree.component';
+
+const routes: Routes = [
+  {path: 'page', component: FrameDeptPageComponent},
+];
+
+@NgModule({
+  imports: [
+    SharedModule,
+    RouterModule.forChild(routes)
+  ],
+  entryComponents: [FrameDeptDetailComponent, FrameDeptTreeComponent],
+  declarations: [FrameDeptDetailComponent, FrameDeptPageComponent, FrameDeptTreeComponent],
+  exports: [
+    RouterModule
+  ]
+})
+export class FrameDeptModule {
+}

+ 84 - 0
src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.html

@@ -0,0 +1,84 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">部门详细信息</h4>
+</div>
+<div class="modal-body" [formGroup]="valForm">
+  <div class="card card-default">
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">部门编号</label>
+        <div class="col-lg-4 col-md-4">
+          <input class="form-control" type="text" formControlName="dept_code" [(ngModel)]="currentEntity.dept_code"
+                 maxlength="32"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">部门名称</label>
+        <div class="col-lg-4 col-md-4">
+          <input class="form-control" type="text" formControlName="dept_name" maxlength="128"
+                 [(ngModel)]="currentEntity.dept_name"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['dept_name'].hasError('required') && (valForm.controls['dept_name'].dirty || valForm.controls['dept_name'].touched)">请输入部门名称</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['dept_name'].hasError('minLength') && (valForm.controls['dept_name'].dirty || valForm.controls['dept_name'].touched)">部门名称至少需要2个字符</span>
+
+        </div>
+      </div>
+
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">部门电话</label>
+        <div class="col-lg-4 col-md-4">
+          <input class="form-control" type="text" formControlName="dept_tel" maxlength="32"
+                 [(ngModel)]="currentEntity.dept_tel"/>
+
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">部门传真</label>
+        <div class="col-lg-4 col-md-4">
+          <input class="form-control" type="text" formControlName="dept_fax" maxlength="32"
+                 [(ngModel)]="currentEntity.dept_fax"/>
+        </div>
+      </div>
+
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">部门负责人</label>
+        <div class="col-lg-4 col-md-4">
+          <input class="form-control" type="text" formControlName="dept_manager" maxlength="32"
+                 [(ngModel)]="currentEntity.dept_manager"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">部门地址</label>
+        <div class="col-lg-4 col-md-4">
+            <textarea class="form-control" type="text" formControlName="dept_addr" maxlength="128"
+                      [(ngModel)]="currentEntity.dept_addr"></textarea>
+        </div>
+      </div>
+    </div>
+    <div class="form-group row">
+      <label class="col-lg-2 col-form-label text-lg-right">父部门</label>
+      <div class="col-lg-10 col-md-10">
+        <select class="form-control" type="number" formControlName="dept_pid" (change)="changeDeptPid($event)"
+                [(ngModel)]="currentEntity.dept_pid">
+          <option [value]="r.dept_id" *ngFor="let r of deptArray"
+                  [innerHTML]="sanitizer.bypassSecurityTrustHtml(r.dept_note)"></option>
+        </select>
+        <span class="text-danger"
+              *ngIf="valForm.controls['dept_pid'].hasError('required') && (valForm.controls['dept_pid'].dirty || valForm.controls['dept_pid'].touched)">父部门不能为空</span>
+      </div>
+
+    </div>
+    <div class="form-group row">
+      <label class="col-lg-2 col-form-labe2 text-lg-right">备注信息</label>
+      <div class="col-lg-10 col-md-10">
+          <textarea class="form-control" type="text" formControlName="dept_desc"
+                    [(ngModel)]="currentEntity.dept_desc"></textarea>
+      </div>
+    </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button"
+          (click)="submitForm('frame/dept/add.htm', {successMsg: '部门添加完成,如需正常使用,请为相应角色添加该部门权限!'})"
+          *ngIf="editModel === 'add'">新增部门
+  </button>
+  <button class="btn btn-primary" type="button" (click)="submitForm('frame/dept/edit.htm')"
+          *ngIf="editModel === 'edit'">
+    修改部门
+  </button>
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.scss


+ 109 - 0
src/app/routes/frame/dept/frame-dept-detail/frame-dept-detail.component.ts

@@ -0,0 +1,109 @@
+import { Component, OnInit } from '@angular/core';
+import {FrameService} from '../../../../core/frame/frame.service';
+import {BsModalRef} from 'ngx-bootstrap';
+import {FormBuilder, Validators} from '@angular/forms';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {DomSanitizer} from '@angular/platform-browser';
+
+@Component({
+  selector: 'app-frame-dept-detail',
+  templateUrl: './frame-dept-detail.component.html',
+  styleUrls: ['./frame-dept-detail.component.scss']
+})
+export class FrameDeptDetailComponent  extends FrameEditComponent implements OnInit {
+
+  deptArray = [];
+  constructor(bsModalRef: BsModalRef, fb: FormBuilder, san: DomSanitizer) {
+    super(bsModalRef, san);
+    this.valForm = fb.group({
+      'dept_code': [null],
+      'dept_name': [null, Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(128)])],
+      'dept_manager': [null, Validators.compose([Validators.required, Validators.minLength(1), Validators.maxLength(32)])],
+      'dept_addr': [null],
+      'dept_tel': [null],
+      'dept_fax': [null],
+      'dept_pid': [null, Validators.required],
+      'dept_desc': [null]
+    });
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      const array = FrameDeptDetailComponent.getDeptArray(this.ResponseArray);
+      for (const s of array) {
+          s.dept_note = `${s.dept_name}`;
+          for (let i = 1; i <= s.dept_level; i ++) {
+            s.dept_note = `&nbsp;&nbsp;` + s.dept_note;
+          }
+          this.deptArray.push(s);
+        }
+
+    }, 10);
+  }
+
+
+  changeDeptPid($event) {
+    for(const r of this.deptArray) {
+      if (r.dept_id + '' === this.currentEntity.dept_pid + '') {
+        this.currentEntity.dept_level = r.dept_level + 1;
+        return;
+      }
+    }
+  }
+
+  public static getDeptArray(resArray) {
+    debugger;
+    const topDeptName = FrameService.getParamValue('FrameDeptName');
+    const dept = {'dept_id': 0, 'dept_name': (topDeptName ? topDeptName : '最高级部门'), 'dept_level': 0};
+    FrameDeptDetailComponent.findChildDept(resArray, dept);
+    const array = [];
+    array.push(dept);
+    FrameDeptDetailComponent.makeDeptArray(dept, array);
+    return array;
+  }
+
+  public static findChildDept(deptArray, dept) {
+    const array = new Array();
+    for (const v of deptArray) {
+      if (v['dept_id'] !== dept['dept_id'] && v['dept_pid'] === dept['dept_id']) {
+        FrameDeptDetailComponent.findChildDept(deptArray, v);
+        array.push(v);
+        dept.childArray = array;
+      }
+    }
+  }
+
+
+  public static makeDeptArray(dept, array) {
+    if (dept.childArray && dept.childArray.length > 0) {
+      for (const c of dept.childArray) {
+        array.push(c);
+        this.makeDeptArray(c, array);
+      }
+    }
+  }
+
+  public static makeOptrDeptArray(deptArray){
+    const array = FrameDeptDetailComponent.getDeptArray(deptArray);
+    let currentArray = [];
+    for (let index = 0; index < array.length; index++) {
+      // 从当前操作员的所属部门开始
+      if (array[index].dept_id === FrameService.FrameOptr.optr_dept) {
+        currentArray = array.slice(index);
+        break;
+      }
+    }
+    const sArray = [];
+    for (const s of array) {
+      s.dept_note = `${s.dept_name}`;
+      const dept_level = FrameService.FrameDept ? FrameService.FrameDept.dept_level : 0;
+      for (let i = dept_level; i < s.dept_level; i++) {
+        s.dept_note = `&nbsp;&nbsp;` + s.dept_note;
+      }
+      sArray.push(s);
+    }
+    return sArray;
+  }
+
+
+}

+ 51 - 0
src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.html

@@ -0,0 +1,51 @@
+<div class="content-heading  justify-content-between">
+  <div>部门管理</div>
+  <div class="float-right">
+    <div class="btn-group mb-1 mr-1" dropdown>
+      <button class="btn dropdown-toggle btn-secondary btn-lg" type="button" dropdownToggle>部门管理
+        <span class="caret"></span>
+      </button>
+      <div *dropdownMenu class="dropdown-menu modal-lg" role="menu">
+        <a class="dropdown-item" href="#" (click)="showModal({'arrayUrl':'frame/dept/all.htm'})">新增部门</a>
+        <div class="dropdown-divider"></div>
+        <a class="dropdown-item" href="#" (click)="showDeptTree({'arrayUrl':'frame/dept/all.htm'})">部门树</a>
+      </div>
+    </div>
+  </div>
+</div>
+<div class=" table-responsive bg-white">
+  <table class="table table-striped table-hover table-bordered">
+    <thead>
+    <tr>
+      <th class="th-index">#</th>
+      <th><span class="table-sort" (click)="pager.sort('dept_code')">部门编号</span></th>
+      <th><span class="table-sort" (click)="pager.sort('dept_name')">部门名称</span></th>
+      <th><span class="table-sort" (click)="pager.sort('dept_manager')">部门经理</span></th>
+      <th><span class="table-sort" (click)="pager.sort('dept_addr')">部门地址</span></th>
+      <th><span class="table-sort" (click)="pager.sort('dept_tel')">部门电话</span></th>
+      <th><span class="table-sort" (click)="pager.sort('dept_fax')">部门传真</span></th>
+      <th class="th-b-2"></th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr *ngFor="let v of pager.getRecords(); let i = index">
+      <td>{{i+1}}</td>
+      <td>{{v.dept_code}}</td>
+      <td>{{v.dept_name}}</td>
+      <td>{{v.dept_manager}}</td>
+      <td>{{v.dept_addr}}</td>
+      <td>{{v.dept_tel}}</td>
+      <td>{{v.dept_fax}}</td>
+      <td ><span class="table-button" (click)="showModal({ResponseEntity:v, arrayUrl:'frame/dept/all.htm'})"><em class="fa-lg fas fa-edit"></em></span>
+        <span class="table-button ml-3 text-danger"
+              (click)="pager.optrRecord('frame/dept/delete.htm', v, {successMsg:'部门删除完成!', confirmMsg: '确定要删除该部门吗?', successMsgType:'Swal'})"><em
+          class="fa-lg fas fa-trash-alt "></em></span>
+
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <frame-pager [url]="'./frame/dept/page.htm'" #pager></frame-pager>
+</div>
+
+

+ 0 - 0
src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.scss


+ 25 - 0
src/app/routes/frame/dept/frame-dept-page/frame-dept-page.component.ts

@@ -0,0 +1,25 @@
+import { Component, OnInit } from '@angular/core';
+import {BsModalService} from 'ngx-bootstrap';
+import {FramePageComponent} from '../../core/FramePageComponent';
+import {FrameDeptTreeComponent} from '../frame-dept-tree/frame-dept-tree.component';
+import {FrameDeptDetailComponent} from '../frame-dept-detail/frame-dept-detail.component';
+
+@Component({
+  selector: 'app-frame-dept-page',
+  templateUrl: './frame-dept-page.component.html',
+  styleUrls: ['./frame-dept-page.component.scss']
+})
+export class FrameDeptPageComponent extends FramePageComponent implements OnInit {
+
+  constructor(private modalService: BsModalService) {
+    super(modalService);
+    this.modalComponent = FrameDeptDetailComponent;
+  }
+
+  ngOnInit() {
+  }
+
+  showDeptTree(param) {
+    this.showComponentModal(FrameDeptTreeComponent, param);
+  }
+}

+ 22 - 0
src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.html

@@ -0,0 +1,22 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">部门树</h4>
+</div>
+<div class="modal-body">
+  <div class="card card-default">
+    <div class="card-body">
+      <tree-root #tree [nodes]="nodes" [focused]="true" [options]="customTemplateStringOptions">
+        <ng-template #treeNodeTemplate let-node>
+          <span title="{{node.data.dept_alias}}">{{ node.data.dept_name }}<span *ngIf="node.data.dept_code">({{node.data.dept_code}})</span></span>
+        </ng-template>
+      </tree-root>
+    </div>
+
+
+  </div>
+
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button" (click)="expandAll()">全部展开</button>
+  <button class="btn btn-primary" type="button" (click)="collapseAll()">全部收缩</button>
+  <button class="btn btn-secondary ml-5" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.scss


+ 73 - 0
src/app/routes/frame/dept/frame-dept-tree/frame-dept-tree.component.ts

@@ -0,0 +1,73 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {ITreeOptions, TreeComponent, TreeNode} from 'angular-tree-component';
+import {BsModalRef} from 'ngx-bootstrap';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+
+@Component({
+  selector: 'app-frame-dept-tree',
+  templateUrl: './frame-dept-tree.component.html',
+  styleUrls: ['./frame-dept-tree.component.scss']
+})
+export class FrameDeptTreeComponent  extends FrameEditComponent implements OnInit {
+  @ViewChild('tree', {static: false}) tree: TreeComponent;
+
+  nodes: any;
+  rootDept: any;
+
+  customTemplateStringOptions: ITreeOptions = {
+    displayField: 'dept_name',
+    isExpandedField: 'expanded',
+    idField: 'dept_id',
+    // hasChildrenField: 'childArray',
+    // nodeHeight: 23,
+    allowDragoverStyling: true,
+    levelPadding: 20,
+    // useVirtualScroll: true,
+    animateExpand: true,
+    scrollOnActivate: true,
+    animateSpeed: 30,
+    animateAcceleration: 1.2
+    // scrollContainer: document.documentElement // HTML
+  }
+
+  constructor(bsModalRef: BsModalRef) {
+    super(bsModalRef);
+  }
+
+  ngOnInit() {
+    const dept = {'dept_id': 0, 'dept_name': '顶级部门', 'dept_level': 0};
+    this.findChildDept(this.ResponseArray, dept);
+    this.rootDept = dept;
+    this.nodes = dept['children'];
+  }
+
+  findChildDept(deptArray, dept) {
+    const array = new Array();
+    for (const v of deptArray) {
+      if (v['dept_id'] !== dept['dept_id'] && v['dept_pid'] === dept['dept_id']) {
+        this.findChildDept(deptArray, v);
+        array.push(v);
+        dept.children = array;
+      }
+    }
+    if (dept.children === undefined || dept.children.length === 0) {
+      dept.hasChildren = false;
+      dept.expanded = false;
+    } else {
+      dept.hasChildren = true;
+      dept.expanded = true;
+    }
+  }
+
+
+  expandAll() {
+    for (const dept of this.rootDept['children']) {
+      this.tree.treeModel.getNodeById(dept.dept_id).expandAll();
+    }
+  }
+  collapseAll() {
+    for (const dept of this.rootDept['children']) {
+      this.tree.treeModel.getNodeById(dept.dept_id).collapseAll();
+    }
+  }
+}

+ 23 - 0
src/app/routes/frame/dict/dict.frame.module.ts

@@ -0,0 +1,23 @@
+import {NgModule} from '@angular/core';
+import {Routes, RouterModule} from '@angular/router';
+import {SharedModule} from '../../../shared/shared.module';
+import { FarmeDictDetailComponent } from './farme-dict-detail/farme-dict-detail.component';
+import {FarmeDictPageComponent} from './farme-dict-page/farme-dict-page.component';
+
+const routes: Routes = [
+  {path: 'page', component: FarmeDictPageComponent},
+];
+
+@NgModule({
+  imports: [
+    SharedModule,
+    RouterModule.forChild(routes)
+  ],
+  entryComponents: [FarmeDictDetailComponent],
+  declarations: [ FarmeDictPageComponent, FarmeDictDetailComponent],
+  exports: [
+    RouterModule
+  ]
+})
+export class FrameDictModule {
+}

+ 86 - 0
src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.html

@@ -0,0 +1,86 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">字典【{{ResponseEntity?.dict_name}}】详细信息</h4>
+</div>
+<div class="modal-body">
+  <div class="row">
+    <div class=" table-responsive bg-white"
+         [ngClass]="{'col-xs-12 col-lg-12': !showDetail, 'col-xs-7 col-lg-7': showDetail}">
+      <table class="table table-striped table-hover table-bordered">
+        <thead>
+        <tr>
+          <th class="th-index">#</th>
+          <th><a href="#" (click)="pager.sort('dict_value')">字典值</a></th>
+          <th><a href="#" (click)="pager.sort('dict_text')">中文描述</a></th>
+          <th><a href="#" (click)="pager.sort('dict_order')">排序</a></th>
+          <th class="th-b-2" *ngIf="ResponseEntity.modify_flag === 'Active'"></th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr *ngFor="let v of pager.getRecords(); let i = index">
+          <td>{{i+1}}</td>
+          <td>{{v.dict_value}}</td>
+          <td>{{v.dict_text}}</td>
+          <td>{{v.dict_order}}</td>
+          <td *ngIf="ResponseEntity.modify_flag === 'Active'"><span class="table-button"
+                                                                    (click)="currentDict = v; showDetail = true; dictMode = 'edit'"><em
+            class="fa-lg fas fa-edit"></em></span>
+            <span class="table-button ml-3 text-danger"
+                  (click)="pager.optrRecord('frame/dict/delete.htm', v, {successMsg:'字典成功删除!', confirmMsg: '确定要删除该字典吗?请慎重进行此操作!', successMsgType:'Swal'})"><em
+              class="fa-lg fas fa-trash-alt "></em></span>
+
+          </td>
+        </tr>
+        </tbody>
+      </table>
+      <frame-pager [url]="'frame/dict/page.htm'" [pagerParams]="{dict_name: ResponseEntity?.dict_name}"
+                   #pager></frame-pager>
+    </div>
+    <div class="col-lg-5 col-xs-5" *ngIf="showDetail"  [formGroup]="valForm">
+      <div class="card card-default">
+        <div class="card-body">
+          <div class="form-group row">
+            <label class="col-lg-5 col-form-label text-lg-right">数据库值</label>
+            <div class="col-lg-7 col-md-7">
+              <input class="form-control" type="text" formControlName="dict_value" maxlength="32"
+                     [readonly]="dictMode === 'edit'"
+                     [(ngModel)]="currentDict.dict_value"/>
+              <span class="text-danger"
+                    *ngIf="valForm.controls['dict_value'].hasError('required') && (valForm.controls['dict_value'].dirty || valForm.controls['dict_value'].touched)">请输入字典数据库值</span>
+
+            </div>
+          </div>
+          <div class="form-group row">
+            <label class="col-lg-5 col-form-label text-lg-right">中文描述</label>
+            <div class="col-lg-7 col-md-7">
+              <input class="form-control" type="text" formControlName="dict_text" maxlength="32"
+                     [(ngModel)]="currentDict.dict_text"/>
+              <span class="text-danger"
+                    *ngIf="valForm.controls['dict_text'].hasError('required') && (valForm.controls['dict_text'].dirty || valForm.controls['dict_text'].touched)">请输入字典中文描述</span>
+            </div>
+          </div>
+          <div class="form-group row">
+            <label class="col-lg-5 col-form-label text-lg-right">字典项排序</label>
+            <div class="col-lg-7 col-md-7">
+              <input class="form-control" type="number" formControlName="dict_order" maxlength="3"
+                     [(ngModel)]="currentDict.dict_order"/>
+              <span class="text-danger"
+                    *ngIf="valForm.controls['dict_order'].hasError('required') && (valForm.controls['dict_order'].dirty || valForm.controls['dict_order'].touched)">请输入字典排序信息</span>
+
+            </div>
+          </div>
+        </div>
+
+        <div class="card-footer text-center">
+          <button class="btn btn-primary" type="button" (click)="saveDict()">保存字典项</button>
+        </div>
+      </div>
+    </div>
+  </div>
+
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button" (click)="showDetail = true; dictMode = 'add'"
+          *ngIf="ResponseEntity.modify_flag === 'Active' && showDetail === false">新增字典项
+  </button>
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.scss


+ 60 - 0
src/app/routes/frame/dict/farme-dict-detail/farme-dict-detail.component.ts

@@ -0,0 +1,60 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {BsModalRef} from 'ngx-bootstrap';
+import {FormBuilder, Validators} from '@angular/forms';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {MsgService} from '../../../../core/msg/msg.service';
+import {AjaxService} from '../../../../core/ajax/ajax.service';
+import {PagerComponent} from '../../../../core/pager/pager.component';
+
+@Component({
+  selector: 'app-farme-dict-detail',
+  templateUrl: './farme-dict-detail.component.html',
+  styleUrls: ['./farme-dict-detail.component.scss']
+})
+export class FarmeDictDetailComponent extends FrameEditComponent implements OnInit {
+
+  showDetail = false;
+  dictMode: any;
+  currentDict =  {};
+  @ViewChild('pager', {static: false}) pager: PagerComponent;
+
+  constructor(bsModalRef: BsModalRef, fb: FormBuilder) {
+    super(bsModalRef);
+    this.valForm = fb.group({
+      'dict_value': [null, Validators.compose([Validators.required, Validators.maxLength(32)])],
+      'dict_text': [null, Validators.compose([Validators.required, Validators.maxLength(32)])],
+      'dict_order': [null, Validators.required]
+    });
+  }
+
+  ngOnInit() {
+
+  }
+
+  saveDict() {
+    if (!this.validForm()) {
+      return;
+    }
+    this.currentDict['dict_name'] = this.ResponseEntity.dict_name;
+
+    let url = 'frame/dict/add.htm';
+    let msg = '确定要增加此字典项吗?';
+    if (this.dictMode === 'edit') {
+      url = 'frame/dict/edit.htm';
+      msg = '确定要修改字典项吗?';
+    }
+
+    MsgService.confirm(msg, () => {
+      AjaxService.request(url, this.currentDict, () => {
+        MsgService.successToaster('字典保存成功!如需生效,请重新加载字典信息!');
+        this.pager.reload();
+        this.dictMode = undefined;
+        this.showDetail = false;
+        this.currentDict = {};
+        this.valForm.markAsUntouched();
+      }, {RequestWithLoading: true});
+    });
+
+  }
+
+}

+ 40 - 0
src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.html

@@ -0,0 +1,40 @@
+<div class="content-heading  justify-content-between">
+  <div>系统字典管理</div>
+  <div class="float-right">
+    <button class="btn btn-danger  btn-lg" type="button" (click)="reloadDict()" frameRole resId="0">重载字典(立即生效)
+      <span class="caret"></span>
+    </button>
+  </div>
+</div>
+<div class=" table-responsive bg-white">
+  <table class="table table-striped table-hover table-bordered">
+    <thead>
+    <tr>
+      <th class="th-index">#</th>
+      <th><a href="#" (click)="pager.sort('dict_name')">字典名称</a></th>
+      <th>中文描述</th>
+      <th>条目数</th>
+      <th>是否允许修改</th>
+      <th>是否框架字典</th>
+      <th class="th-b-1"></th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr *ngFor="let v of pager.getRecords(); let i = index">
+      <td>{{i+1}}</td>
+      <td>{{v.dict_name}}</td>
+      <td>{{v.dict_desc}}</td>
+      <td>{{v.dict_total}}</td>
+      <td [innerHTML]="v.modify_flag | frameStatus"></td>
+      <td [innerHTML]="v.frame_flag | frameStatus"></td>
+      <td><span class="table-button" (click)="showModal({ResponseEntity:v})" frameRole res_id="0"><em
+        class="fa-lg fas fa-edit"></em></span>
+
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <frame-pager [url]="'frame/dict/type/page.htm'" #pager></frame-pager>
+</div>
+
+

+ 0 - 0
src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.scss


+ 34 - 0
src/app/routes/frame/dict/farme-dict-page/farme-dict-page.component.ts

@@ -0,0 +1,34 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {AjaxService} from '../../../../core/ajax/ajax.service';
+import {BsModalService} from 'ngx-bootstrap';
+import {MsgService} from '../../../../core/msg/msg.service';
+import {FramePageComponent} from '../../core/FramePageComponent';
+import {FarmeDictDetailComponent} from '../farme-dict-detail/farme-dict-detail.component';
+import {PagerComponent} from '../../../../core/pager/pager.component';
+
+@Component({
+  selector: 'app-farme-dict-page',
+  templateUrl: './farme-dict-page.component.html',
+  styleUrls: ['./farme-dict-page.component.scss']
+})
+export class FarmeDictPageComponent  extends FramePageComponent implements OnInit {
+
+  constructor(private modalService: BsModalService) {
+    super(modalService);
+    this.modalComponent = FarmeDictDetailComponent;
+  }
+
+  ngOnInit() {
+  }
+
+  reloadDict() {
+    MsgService.confirm(`确定要重新加载系统字典吗?如果字典较多,该操作可能需要比较长的时间,请谨慎使用该功能!`, () => {
+      AjaxService.request('frame/dict/reload.htm', {}, () => {
+        MsgService.successAlert(`字典加载成功,后台字典已经生效,前端字典需重新登录!`);
+
+      }, { RequestWithLoading: true});
+    });
+  }
+
+
+}

+ 1 - 0
src/app/routes/frame/frame.component.html

@@ -0,0 +1 @@
+<router-outlet></router-outlet>

+ 14 - 0
src/app/routes/frame/frame.component.ts

@@ -0,0 +1,14 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-frame',
+  templateUrl: './frame.component.html'
+})
+export class FrameComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}

+ 29 - 0
src/app/routes/frame/frame.module.ts

@@ -0,0 +1,29 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import {FrameComponent} from './frame.component';
+import {SharedModule} from '../../shared/shared.module';
+
+const routes: Routes = [
+    { path: '',  component: FrameComponent, children: [
+        { path: 'res', loadChildren: './res/res.frame.module#FrameResModule' },
+        { path: 'param', loadChildren: './param/param.frame.module#FrameParamModule' },
+        { path: 'dict', loadChildren: './dict/dict.frame.module#FrameDictModule' },
+        { path: 'dept', loadChildren: './dept/dept.frame.module#FrameDeptModule' },
+        { path: 'role', loadChildren: './role/role.frame.module#FrameRoleModule' },
+        { path: 'optr', loadChildren: './optr/optr.frame.module#FrameOptrModule' },
+        { path: 'thread', loadChildren: './thread/thread.frame.module#FrameThreadModule' }
+      ]
+    }
+];
+
+@NgModule({
+    imports: [
+        SharedModule,
+        RouterModule.forChild(routes)
+    ],
+    declarations: [FrameComponent],
+    exports: [
+        RouterModule
+    ]
+})
+export class FrameModule { }

+ 135 - 0
src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.html

@@ -0,0 +1,135 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">操作员详细信息</h4>
+</div>
+<div class="modal-body" [formGroup]="valForm">
+  <div class="card card-default">
+    <div class="card-header">必填信息</div>
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">登录名称</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="login_name" [readonly]="editModel === 'edit'"
+                 [(ngModel)]="currentEntity.login_name" maxlength="16"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['login_name'].hasError('required') && (valForm.controls['login_name'].dirty || valForm.controls['login_name'].touched)">请输入登录名称</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['login_name'].hasError('minlength') && (valForm.controls['login_name'].dirty || valForm.controls['login_name'].touched)">登录名称至少需要3个字符</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['login_name'].hasError('eName') && (valForm.controls['login_name'].dirty || valForm.controls['login_name'].touched)">{{valForm.getError('eName', 'login_name')}}</span>
+        </div>
+        <ng-container formGroupName="passwordGroup">
+          <label class="col-lg-2 col-form-label text-lg-right">登录密码</label>
+          <div class="col-lg-2 col-md-2">
+            <input class="form-control" type="password" formControlName="password" maxlength="16"
+                   [(ngModel)]="currentEntity.login_pass"/>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('required',['passwordGroup','password']) && (valForm.get('passwordGroup').get('password').dirty || valForm.get('passwordGroup').get('password').touched)">请输入登录密码</span>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('minlength',['passwordGroup','password']) && (valForm.get('passwordGroup').get('password').dirty || valForm.get('passwordGroup').get('password').touched)">密码至少需要6位</span>
+
+          </div>
+          <label class="col-lg-2 col-form-label text-lg-right">密码确认</label>
+          <div class="col-lg-2 col-md-2">
+            <input class="form-control" type="password" formControlName="pconfirm" maxlength="16"/> <span
+            class="text-danger"
+            *ngIf="valForm.hasError('required',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">请输入确认密码</span>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('minlength',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">密码至少需要6位</span>
+
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('password','passwordGroup') && !valForm.hasError('required',['passwordGroup','pconfirm'])  && !valForm.hasError('minlength',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">{{valForm.getError('password', 'passwordGroup')}}</span>
+          </div>
+        </ng-container>
+
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">真实姓名</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_name"
+                 [(ngModel)]="currentEntity.optr_name" maxlength="32"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('required') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">请输入真实姓名</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('minlength') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">姓名至少需要2个字符</span>
+           </div>
+        <label class="col-lg-2 col-form-label text-lg-right">性别信息</label>
+        <div class="col-lg-2 col-md-2">
+          <select class="form-control" formControlName="optr_sex" frameDict [dictName]="'FrameSex'"
+                  [tipFlag]="false" [(ngModel)]="currentEntity.optr_sex"> </select>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">使用状态</label>
+        <div class="col-lg-2 col-md-2">
+          <select class="form-control" formControlName="optr_status" frameDict [dictName]="'FrameStatus'"
+                  [tipFlag]="false" [(ngModel)]="currentEntity.optr_status"> </select>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">移动电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_mobile" [(ngModel)]="currentEntity.optr_mobile"
+                 maxlength="11"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">移动电话必填</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('mobile') && !valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">电话格式错误,请输入11位手机号</span>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">所在岗位</label>
+        <div class="col-lg-6 col-md-6">
+          <select class="form-control" formControlName="optr_dept" [(ngModel)]="currentEntity.optr_dept">
+            <option [value]="r.dept_id" *ngFor="let r of deptArray"
+                    [innerHTML]="sanitizer.bypassSecurityTrustHtml(r.dept_note)"></option>
+          </select>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_dept'].hasError('required') && (valForm.controls['optr_dept'].dirty || valForm.controls['optr_dept'].touched)">岗位信息不能为空</span>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="card card-default">
+    <div class="card-header">选填信息</div>
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">办公电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_tel" [(ngModel)]="currentEntity.optr_tel"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">传真号码</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_fax" [(ngModel)]="currentEntity.optr_fax"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">职务信息</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_post" [(ngModel)]="currentEntity.optr_post"
+                 maxlength="24"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">邮件地址</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_email" [(ngModel)]="currentEntity.optr_email"
+                 maxlength="32"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">办公地址</label>
+        <div class="col-lg-6 col-md-6">
+          <input class="form-control" type="text" formControlName="optr_addr" [(ngModel)]="currentEntity.optr_addr"
+                 maxlength="256"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">备注信息</label>
+        <div class="col-lg-10 col-md-10">
+          <textarea class="form-control" type="text" formControlName="optr_desc" [(ngModel)]="currentEntity.optr_desc"
+                    maxlength="128"></textarea>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button"
+          (click)="submitForm('frame/optr/add.htm', {successMsg: '操作员添加完成,如需正常使用,请为该操作员添加角色信息!'})">新增操作员
+  </button>
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.scss


+ 70 - 0
src/app/routes/frame/optr/frame-optr-create/frame-optr-create.component.ts

@@ -0,0 +1,70 @@
+import {Component, OnInit} from '@angular/core';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {BsModalRef} from 'ngx-bootstrap';
+import {FormBuilder, Validators} from '@angular/forms';
+import {mobileValidator} from '../../../../shared/validator/mobile.validator';
+import {DomSanitizer} from '@angular/platform-browser';
+import {eNameValidator} from '../../../../shared/validator/ename.validator';
+import {passswordValidator} from '../../../../shared/validator/password.validator';
+import {FrameDeptDetailComponent} from '../../dept/frame-dept-detail/frame-dept-detail.component';
+import {FrameService} from '../../../../core/frame/frame.service';
+
+@Component({
+  selector: 'app-frame-optr-create',
+  templateUrl: './frame-optr-create.component.html',
+  styleUrls: ['./frame-optr-create.component.scss']
+})
+export class FrameOptrCreateComponent extends FrameEditComponent implements OnInit {
+
+  deptArray = [];
+
+  constructor(bsModalRef: BsModalRef, fb: FormBuilder, san: DomSanitizer) {
+    super(bsModalRef, san);
+    this.valForm = fb.group({
+      'login_name': [null, Validators.compose([eNameValidator, Validators.required, Validators.minLength(3), Validators.maxLength(32)])],
+      'optr_name': [null, Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(32)])],
+      'optr_sex': [null],
+      'optr_status': [null],
+      'optr_email': [null],
+      'optr_mobile': [null, Validators.compose([Validators.required, mobileValidator])],
+      'optr_tel': [null],
+      'optr_fax': [null],
+      'optr_addr': [null],
+      'optr_post': [null],
+      'optr_dept': [null],
+      'optr_desc': [null],
+      'passwordGroup': fb.group({
+        'password': [null, Validators.compose([Validators.required, Validators.minLength(6)])],
+        'pconfirm': [null, Validators.compose([Validators.required, Validators.minLength(6)])]
+      }, {validator: passswordValidator})
+    });
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      debugger;
+      // 设置默认值
+      this.currentEntity = {optr_status: 'Active', optr_sex: '男', optr_dept: FrameService.FrameOptr.optr_dept}
+      const array = FrameDeptDetailComponent.getDeptArray(this.ResponseArray);
+      let currentArray = [];
+      for (let index = 0; index < array.length; index++) {
+        // 从当前操作员的所属部门开始
+        if (array[index].dept_id === FrameService.FrameOptr.optr_dept) {
+          currentArray = array.slice(index);
+          break;
+        }
+      }
+      for (const s of array) {
+        s.dept_note = `${s.dept_name}`;
+        const dept_level = FrameService.FrameDept ? FrameService.FrameDept.dept_level : 0;
+        for (let i = dept_level; i < s.dept_level; i++) {
+          s.dept_note = `&nbsp;&nbsp;` + s.dept_note;
+        }
+        this.deptArray.push(s);
+      }
+
+    }, 10);
+  }
+
+
+}

+ 98 - 0
src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.html

@@ -0,0 +1,98 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">操作员【{{currentEntity.login_name}}】详细信息</h4>
+</div>
+<div class="modal-body" [formGroup]="valForm">
+  <div class="card card-default">
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">登录名称</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" [value]="currentEntity.login_name" [readonly]="true"/></div>
+
+        <label class="col-lg-2 col-form-label text-lg-right">真实姓名</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_name"
+                 [(ngModel)]="currentEntity.optr_name" maxlength="32"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('required') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">请输入真实姓名</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('minlength') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">姓名至少需要2个字符</span>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">性别信息</label>
+        <div class="col-lg-2 col-md-2">
+          <select class="form-control" formControlName="optr_sex" frameDict [dictName]="'FrameSex'"
+                  [tipFlag]="false" [(ngModel)]="currentEntity.optr_sex"> </select>
+        </div>
+
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">移动电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_mobile" [(ngModel)]="currentEntity.optr_mobile"
+                 maxlength="11"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">移动电话必填</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('mobile') && !valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">电话格式错误,请输入11位手机号</span>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">所在岗位</label>
+        <div class="col-lg-6 col-md-6">
+          <input class="form-control" type="text" [value]="currentEntity.dept_name" [readonly]="true"/></div>
+      </div>
+
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">办公电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_tel" [(ngModel)]="currentEntity.optr_tel"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">传真号码</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_fax" [(ngModel)]="currentEntity.optr_fax"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">职务信息</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_post" [(ngModel)]="currentEntity.optr_post"
+                 maxlength="24"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">邮件地址</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_email" [(ngModel)]="currentEntity.optr_email"
+                 maxlength="32"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">办公地址</label>
+        <div class="col-lg-6 col-md-6">
+          <input class="form-control" type="text" formControlName="optr_addr" [(ngModel)]="currentEntity.optr_addr"
+                 maxlength="256"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">备注信息</label>
+        <div class="col-lg-10 col-md-10">
+          <textarea class="form-control" type="text" formControlName="optr_desc" [(ngModel)]="currentEntity.optr_desc"
+                    maxlength="128"></textarea>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+<div class="modal-footer justify-content-between">
+  <div>
+    <button class="btn btn-primary" type="button"
+            (click)="openPassword()">修改登录密码
+    </button>
+    <button class="btn btn-primary ml-2" type="button"
+            (click)="uploader.uploadFiles()">上传照片
+    </button>
+  </div>
+  <div>
+    <button class="btn btn-primary" type="button"
+            (click)="modifyOptr()">修改信息
+    </button>
+    <button class="btn btn-secondary ml-2" type="button" (click)="closeWindow()">取消操作</button>
+  </div>
+</div>
+<frame-uploader [uploadUrl]="'frame/optr/image/upload.htm'" [uploadParams]="{optr_id: currentEntity.optr_id}" (allUpload)="uploadOptrImage()" #uploader></frame-uploader>

+ 0 - 0
src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.scss


+ 69 - 0
src/app/routes/frame/optr/frame-optr-edit/frame-optr-edit.component.ts

@@ -0,0 +1,69 @@
+import {Component, OnInit} from '@angular/core';
+import {FormBuilder, Validators} from '@angular/forms';
+import {DomSanitizer} from '@angular/platform-browser';
+import {mobileValidator} from '../../../../shared/validator/mobile.validator';
+import {AjaxService} from '../../../../core/ajax/ajax.service';
+import {FrameDeptDetailComponent} from '../../dept/frame-dept-detail/frame-dept-detail.component';
+import {FrameService} from '../../../../core/frame/frame.service';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {BsModalRef, BsModalService} from 'ngx-bootstrap';
+import {MsgService} from '../../../../core/msg/msg.service';
+import {FrameOptrPasswordComponent} from '../frame-optr-password/frame-optr-password.component';
+
+@Component({
+  selector: 'app-frame-optr-edit',
+  templateUrl: './frame-optr-edit.component.html',
+  styleUrls: ['./frame-optr-edit.component.scss']
+})
+export class FrameOptrEditComponent extends FrameEditComponent implements OnInit {
+
+  constructor(public modalService: BsModalService, bsModalRef: BsModalRef, fb: FormBuilder) {
+    super(bsModalRef);
+    this.valForm = fb.group({
+      'optr_name': [null, Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(32)])],
+      'optr_sex': [null],
+      'optr_email': [null],
+      'optr_mobile': [null, Validators.compose([Validators.required, mobileValidator])],
+      'optr_tel': [null],
+      'optr_fax': [null],
+      'optr_addr': [null],
+      'optr_post': [null],
+      'optr_desc': [null]
+    });
+  }
+
+  ngOnInit() {
+    this.currentEntity = Object.assign({}, FrameService.FrameOptr);
+    this.currentEntity.optr_image = undefined;
+    this.currentEntity.dept_name = FrameService.FrameDept.dept_name;
+    this.currentEntity.resMap = undefined;
+  }
+
+  modifyOptr() {
+    this.submitForm('frame/optr/edit.htm', {successMsg: '操作员信息已修改!'},  () => {
+      MsgService.successAlert('操作员信息已完善,系统将重新加载!', undefined, () => {
+        location.reload();
+      });
+    });
+  }
+
+  openPassword() {
+    const modal = Object.assign({},  {
+      animated: true,
+      keyboard: false,
+      backdrop: true,
+      ignoreBackdropClick: true,
+      initialState: {optrModel: 'edit', optr: FrameService.FrameOptr},
+      class: 'modal-5'
+    });
+    this.modalService.show(FrameOptrPasswordComponent, modal);
+    this.bsModalRef.hide();
+  }
+
+
+  uploadOptrImage() {
+    MsgService.successAlert('操作员照片信息已保存,系统将重新加载!', undefined, () => {
+      location.reload();
+    });
+  }
+}

+ 99 - 0
src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.html

@@ -0,0 +1,99 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">操作员【{{currentEntity.login_name}}】详细信息</h4>
+</div>
+<div class="modal-body" [formGroup]="valForm">
+  <div class="card card-default">
+    <div class="card-header">必填信息</div>
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">使用状态</label>
+        <div class="col-lg-2 col-md-2">
+          <select class="form-control" formControlName="optr_status" frameDict [dictName]="'FrameStatus'"
+                  [tipFlag]="false" [(ngModel)]="currentEntity.optr_status"> </select>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">真实姓名</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_name"
+                 [(ngModel)]="currentEntity.optr_name" maxlength="32"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('required') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">请输入真实姓名</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_name'].hasError('minlength') && (valForm.controls['optr_name'].dirty || valForm.controls['optr_name'].touched)">姓名至少需要2个字符</span>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">性别信息</label>
+        <div class="col-lg-2 col-md-2">
+          <select class="form-control" formControlName="optr_sex" frameDict [dictName]="'FrameSex'"
+                  [tipFlag]="false" [(ngModel)]="currentEntity.optr_sex"> </select>
+        </div>
+
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">移动电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_mobile" [(ngModel)]="currentEntity.optr_mobile"
+                 maxlength="11"/>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">移动电话必填</span>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_mobile'].hasError('mobile') && !valForm.controls['optr_mobile'].hasError('required') && (valForm.controls['optr_mobile'].dirty || valForm.controls['optr_mobile'].touched)">电话格式错误,请输入11位手机号</span>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">所在岗位</label>
+        <div class="col-lg-6 col-md-6">
+          <select class="form-control" formControlName="optr_dept" [(ngModel)]="currentEntity.optr_dept">
+            <option [value]="r.dept_id" *ngFor="let r of deptArray"
+                    [innerHTML]="sanitizer.bypassSecurityTrustHtml(r.dept_note)"></option>
+          </select>
+          <span class="text-danger"
+                *ngIf="valForm.controls['optr_dept'].hasError('required') && (valForm.controls['optr_dept'].dirty || valForm.controls['optr_dept'].touched)">岗位信息不能为空</span>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div class="card card-default">
+    <div class="card-header">选填信息</div>
+    <div class="card-body">
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">办公电话</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_tel" [(ngModel)]="currentEntity.optr_tel"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">传真号码</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_fax" [(ngModel)]="currentEntity.optr_fax"
+                 maxlength="24"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">职务信息</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_post" [(ngModel)]="currentEntity.optr_post"
+                 maxlength="24"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">邮件地址</label>
+        <div class="col-lg-2 col-md-2">
+          <input class="form-control" type="text" formControlName="optr_email" [(ngModel)]="currentEntity.optr_email"
+                 maxlength="32"/>
+        </div>
+        <label class="col-lg-2 col-form-label text-lg-right">办公地址</label>
+        <div class="col-lg-6 col-md-6">
+          <input class="form-control" type="text" formControlName="optr_addr" [(ngModel)]="currentEntity.optr_addr"
+                 maxlength="256"/>
+        </div>
+      </div>
+      <div class="form-group row">
+        <label class="col-lg-2 col-form-label text-lg-right">备注信息</label>
+        <div class="col-lg-10 col-md-10">
+          <textarea class="form-control" type="text" formControlName="optr_desc" [(ngModel)]="currentEntity.optr_desc"
+                    maxlength="128"></textarea>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button"
+          (click)="submitForm('frame/optr/edit.htm', {successMsg: '操作员信息已修改!'})">修改信息
+  </button>
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.scss


+ 63 - 0
src/app/routes/frame/optr/frame-optr-modify/frame-optr-modify.component.ts

@@ -0,0 +1,63 @@
+import {Component, OnInit} from '@angular/core';
+import {FormBuilder, Validators} from '@angular/forms';
+import {DomSanitizer} from '@angular/platform-browser';
+import {mobileValidator} from '../../../../shared/validator/mobile.validator';
+import {eNameValidator} from '../../../../shared/validator/ename.validator';
+import {passswordValidator} from '../../../../shared/validator/password.validator';
+import {FrameDeptDetailComponent} from '../../dept/frame-dept-detail/frame-dept-detail.component';
+import {FrameService} from '../../../../core/frame/frame.service';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {BsModalRef} from 'ngx-bootstrap';
+import {AjaxService} from '../../../../core/ajax/ajax.service';
+
+@Component({
+  selector: 'app-frame-optr-modify',
+  templateUrl: './frame-optr-modify.component.html',
+  styleUrls: ['./frame-optr-modify.component.scss']
+})
+export class FrameOptrModifyComponent extends FrameEditComponent implements OnInit {
+
+  deptArray = [];
+
+  constructor(bsModalRef: BsModalRef, fb: FormBuilder, san: DomSanitizer) {
+    super(bsModalRef, san);
+    this.valForm = fb.group({
+      'optr_name': [null, Validators.compose([Validators.required, Validators.minLength(2), Validators.maxLength(32)])],
+      'optr_sex': [null],
+      'optr_status': [null],
+      'optr_email': [null],
+      'optr_mobile': [null, Validators.compose([Validators.required, mobileValidator])],
+      'optr_tel': [null],
+      'optr_fax': [null],
+      'optr_addr': [null],
+      'optr_post': [null],
+      'optr_dept': [null],
+      'optr_desc': [null]
+    });
+  }
+
+  ngOnInit() {
+    AjaxService.requestArray('frame/dept/all.htm', {}, (ResponseArray) => {
+      const array = FrameDeptDetailComponent.getDeptArray(ResponseArray);
+      let currentArray = [];
+      for (let index = 0; index < array.length; index++) {
+        // 从当前操作员的所属部门开始
+        if (array[index].dept_id === FrameService.FrameOptr.optr_dept) {
+          currentArray = array.slice(index);
+          break;
+        }
+      }
+      for (const s of array) {
+        s.dept_note = `${s.dept_name}`;
+        const dept_level = FrameService.FrameDept ? FrameService.FrameDept.dept_level : 0;
+        for (let i = dept_level; i < s.dept_level; i++) {
+          s.dept_note = `&nbsp;&nbsp;` + s.dept_note;
+        }
+        this.deptArray.push(s);
+      }
+    });
+    this.currentEntity.optr_image = undefined;
+  }
+
+
+}

+ 55 - 0
src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.html

@@ -0,0 +1,55 @@
+<div class="content-heading  justify-content-between">
+  <div>操作员管理</div>
+  <div class="float-right">
+    <div class="btn-group mb-1 mr-1" dropdown>
+      <button class="btn dropdown-toggle btn-secondary btn-lg" type="button" dropdownToggle>用户管理
+        <span class="caret"></span>
+      </button>
+      <div *dropdownMenu class="dropdown-menu modal-lg" role="menu">
+        <a class="dropdown-item" href="#" (click)="showCreateModal({'arrayUrl':'frame/dept/all.htm'})">新增操作员</a>
+        <div class="dropdown-divider"></div>
+      </div>
+    </div>
+  </div>
+</div>
+<div class=" table-optrponsive bg-white">
+  <table class="table table-striped table-hover table-bordered">
+    <thead>
+    <tr>
+      <th class="th-index">#</th>
+      <th><a href="#" (click)="pager.sort('login_name')">登录名</a></th>
+      <th><a href="#" (click)="pager.sort('optr_name')">实际名称</a></th>
+      <th>性别</th>
+      <th>状态</th>
+      <th>所属角色</th>
+      <th>所属部门</th>
+      <th>创建人</th>
+      <th>创建时间</th>
+      <th class="th-b-3"></th>
+    </tr>
+    </thead>
+    <tbody>
+    <tr *ngFor="let v of pager.getRecords(); let i = index">
+      <td>{{i+1}}</td>
+      <td>{{v.login_name}}</td>
+      <td>{{v.optr_name}}</td>
+      <td>{{v.optr_sex | frameDict : 'FrameSex'}}</td>
+      <td [innerHTML]="v.optr_status | frameStatus"></td>
+      <td>{{v.role_names}}</td>
+      <td>{{v.dept_name}}</td>
+      <td>{{v.create_optr_name}}</td>
+      <td>{{v.create_time}}</td>
+      <td><span class="table-button" (click)="showModal({entityUrl:'frame/optr/find.htm', entityParam: {optr_id: v.optr_id}})"><em class="fa-lg fas fa-edit"></em></span>
+        <span class="table-button ml-3 text-info" (click)="showOptrRole(v)"><em class="fa-lg fas fa-users"></em></span>
+        <span class="table-button ml-3 text-danger"
+              (click)="pager.optrRecord('frame/optr/delete.htm', v, {successMsg:'操作员删除完成!', confirmMsg: '确定要删除该操作员吗?', successMsgType:'Swal'})"><em
+          class="fa-lg fas fa-trash-alt "></em></span>
+
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <frame-pager [url]="'./frame/optr/page.htm'" #pager></frame-pager>
+</div>
+
+

+ 0 - 0
src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.scss


+ 31 - 0
src/app/routes/frame/optr/frame-optr-page/frame-optr-page.component.ts

@@ -0,0 +1,31 @@
+import { Component, OnInit } from '@angular/core';
+import {BsModalService} from 'ngx-bootstrap';
+import {FramePageComponent} from '../../core/FramePageComponent';
+import {FrameOptrModifyComponent} from '../frame-optr-modify/frame-optr-modify.component';
+import {FrameOptrRoleComponent} from '../frame-optr-role/frame-optr-role.component';
+import {FrameOptrCreateComponent} from '../frame-optr-create/frame-optr-create.component';
+
+@Component({
+  selector: 'app-frame-optr-page',
+  templateUrl: './frame-optr-page.component.html',
+  styleUrls: ['./frame-optr-page.component.scss']
+})
+export class FrameOptrPageComponent extends FramePageComponent implements OnInit {
+
+  constructor(private modalService: BsModalService) {
+    super(modalService);
+    this.modalComponent = FrameOptrModifyComponent;
+  }
+
+  ngOnInit() {
+  }
+
+
+  showOptrRole (optr) {
+    this.showComponentModal(FrameOptrRoleComponent,{entityUrl: 'frame/optr/find.htm', entityParam: {optr_id: optr.optr_id}});
+  }
+
+  showCreateModal() {
+    this.showComponentModal(FrameOptrCreateComponent);
+  }
+}

+ 57 - 0
src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.html

@@ -0,0 +1,57 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">修改【{{optr.optr_name}}({{optr.login_name}})】登录密码</h4>
+</div>
+<div class="modal-body" [formGroup]="valForm">
+  <div class="card card-default">
+    <div class="card-body">
+      <div class="form-group row" *ngIf="optrModel === 'edit'">
+        <label class="col-lg-5 col-form-label text-lg-right">原始密码</label>
+        <div class="col-lg-7 col-md-7">
+          <input class="form-control" type="password" formControlName="old_pass" maxlength="16"
+                 [(ngModel)]="currentEntity.old_password"/>
+          <span class="text-danger"
+                *ngIf="valForm.hasError('required','old_pass') && (valForm.get('old_pass').dirty || valForm.get('old_pass').touched)">请输入原始密码</span>
+          <span class="text-danger"
+                *ngIf="valForm.hasError('minlength','old_pass') && (valForm.get('old_pass').dirty || valForm.get('old_pass').touched)">密码至少需要6位</span>
+
+        </div>
+      </div>
+
+      <ng-container formGroupName="passwordGroup">
+        <div class="form-group row">
+          <label class="col-lg-5 col-form-label text-lg-right">新密码</label>
+          <div class="col-lg-7 col-md-7">
+            <input class="form-control" type="password" formControlName="password" maxlength="16"
+                   [(ngModel)]="currentEntity.new_pass"/>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('required',['passwordGroup','password']) && (valForm.get('passwordGroup').get('password').dirty || valForm.get('passwordGroup').get('password').touched)">请输入登录密码</span>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('minlength',['passwordGroup','password']) && (valForm.get('passwordGroup').get('password').dirty || valForm.get('passwordGroup').get('password').touched)">密码至少需要6位</span>
+
+          </div>
+        </div>
+        <div class="form-group row">
+          <label class="col-lg-5 col-form-label text-lg-right">密码确认</label>
+          <div class="col-lg-7 col-md-7">
+            <input class="form-control" type="password" formControlName="pconfirm" maxlength="16"/> <span
+            class="text-danger"
+            *ngIf="valForm.hasError('required',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">请输入确认密码</span>
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('minlength',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">密码至少需要6位</span>
+
+            <span class="text-danger"
+                  *ngIf="valForm.hasError('password','passwordGroup') && !valForm.hasError('required',['passwordGroup','pconfirm'])  && !valForm.hasError('minlength',['passwordGroup','pconfirm']) && (valForm.get('passwordGroup').get('pconfirm').dirty || valForm.get('passwordGroup').get('pconfirm').touched)">{{valForm.getError('password', 'passwordGroup')}}</span>
+          </div>
+
+        </div>
+      </ng-container>
+
+    </div>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-primary" type="button"
+          (click)="savePassword()">修改密码
+  </button>
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">取消操作</button>
+</div>

+ 0 - 0
src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.scss


+ 55 - 0
src/app/routes/frame/optr/frame-optr-password/frame-optr-password.component.ts

@@ -0,0 +1,55 @@
+import { Component, OnInit } from '@angular/core';
+import {FormBuilder, Validators} from '@angular/forms';
+import {passswordValidator} from '../../../../shared/validator/password.validator';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {BsModalRef} from 'ngx-bootstrap';
+import {MsgService} from '../../../../core/msg/msg.service';
+import {AjaxService} from '../../../../core/ajax/ajax.service';
+
+@Component({
+  selector: 'app-frame-optr-password',
+  templateUrl: './frame-optr-password.component.html',
+  styleUrls: ['./frame-optr-password.component.scss']
+})
+export class FrameOptrPasswordComponent extends FrameEditComponent implements OnInit {
+
+  optrModel = 'edit';
+  optr: any;
+
+  constructor(public bsModalRef: BsModalRef, public fb: FormBuilder) {
+    super(bsModalRef);
+    this.valForm = this.fb.group({
+      'old_pass': [null, Validators.compose([Validators.required, Validators.minLength(6)])],
+      'passwordGroup': this.fb.group({
+        'password': [null, Validators.compose([Validators.required, Validators.minLength(6)])],
+        'pconfirm': [null, Validators.compose([Validators.required, Validators.minLength(6)])]
+      }, {validator: passswordValidator})
+    });
+  }
+
+  ngOnInit() {
+    setTimeout( () => {
+      if (this.bsModalRef.content.optrModel === 'admin') {
+        this.optrModel = 'admin';
+        this.valForm.get('old_pass').setValidators(null);
+      }
+      this.currentEntity = { optr_id: this.bsModalRef.content.optr.optr_id};
+    }, 10);
+  }
+
+
+  savePassword() {
+    this.valForm.markAllAsTouched();
+    if (!this.validForm()) {
+      return;
+    }
+    MsgService.confirm('确定要修改登录密码吗?', () => {
+      AjaxService.request('frame/optr/passwd.htm', this.currentEntity, () => {
+          MsgService.successAlert('操作员登录密码修改成功,请使用新密码登录!',  '', () => {
+            this.bsModalRef.hide();
+          });
+      }, {RequestWithLoading: true});
+    });
+  }
+
+}

+ 43 - 0
src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.html

@@ -0,0 +1,43 @@
+<div class="modal-header">
+  <h4 class="modal-title pull-left">【{{ResponseEntity.optr_name}}({{ResponseEntity.login_name}})】角色列表</h4>
+</div>
+<div class="modal-body">
+  <div class=" table-responsive bg-white">
+    <table class="table table-striped table-hover table-bordered">
+      <thead>
+      <tr>
+        <th>#</th>
+        <th><a href="#" (click)="pager.sort('role_name')">角色名称</a></th>
+        <th>是否已分配</th>
+        <th>操作员数</th>
+        <th>资源总数</th>
+        <th>主页地址</th>
+        <th class="th-b-4"></th>
+      </tr>
+      </thead>
+      <tbody>
+      <tr *ngFor="let v of pager.getRecords(); let i = index">
+        <td>{{i+1}}</td>
+        <td>{{v.role_name}}</td>
+        <td><span *ngIf="v.optr_id" class="text-success">已分配</span></td>
+
+        <td>{{v.optr_count}}</td>
+        <td>{{v.res_count}}</td>
+        <td>{{v.home_page}}</td>
+        <td>
+          <button class="btn btn-primary btn-sm" type="button" (click)="pager.optrRecord('frame/optr/role/dist.htm', {optr_id: ResponseEntity.optr_id, role_id: v.role_id}, {successMsg:'已成功为操作员分配角色权限!', confirmMsg: '确定要给该操作员分配角色【'+ v.role_name +'】吗?', successMsgType:'Swal'})" *ngIf="v.optr_id === undefined">
+            分配权限
+          </button>
+          <button class="btn btn-danger btn-sm" type="button" (click)="pager.optrRecord('frame/optr/role/recover.htm',  {optr_id: ResponseEntity.optr_id, role_id: v.role_id}, {successMsg:'已成功回收操作员的角色权限!', confirmMsg: '确定要回收该操作员的角色【'+ v.role_name +'】吗?', successMsgType:'Swal'})" *ngIf="v.optr_id !== undefined">
+            取消分配
+          </button>
+        </td>
+      </tr>
+      </tbody>
+    </table>
+    <frame-pager [url]="'./frame/role/page.htm'" [pagerParams]="{optr_id: ResponseEntity.optr_id}" #pager></frame-pager>
+  </div>
+</div>
+<div class="modal-footer">
+  <button class="btn btn-secondary" type="button" (click)="closeWindow()">关闭窗口</button>
+</div>

+ 0 - 0
src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.scss


+ 26 - 0
src/app/routes/frame/optr/frame-optr-role/frame-optr-role.component.ts

@@ -0,0 +1,26 @@
+import { Component, OnInit } from '@angular/core';
+import {FormBuilder, Validators} from '@angular/forms';
+import {FrameEditComponent} from '../../core/FrameEditComponent';
+import {BsModalRef} from 'ngx-bootstrap';
+
+@Component({
+  selector: 'app-frame-optr-role',
+  templateUrl: './frame-optr-role.component.html',
+  styleUrls: ['./frame-optr-role.component.scss']
+})
+export class FrameOptrRoleComponent extends FrameEditComponent implements OnInit {
+
+  optrModel = 'edit';
+  optr: any;
+
+  constructor(public bsModalRef: BsModalRef, public fb: FormBuilder) {
+    super(bsModalRef);
+
+  }
+
+  ngOnInit() {
+
+  }
+
+
+}

+ 25 - 0
src/app/routes/frame/optr/optr.frame.module.ts

@@ -0,0 +1,25 @@
+import {NgModule} from '@angular/core';
+import {Routes, RouterModule} from '@angular/router';
+import {SharedModule} from '../../../shared/shared.module';
+import {FrameOptrPageComponent} from './frame-optr-page/frame-optr-page.component';
+import { FrameOptrCreateComponent } from './frame-optr-create/frame-optr-create.component';
+import { FrameOptrModifyComponent } from './frame-optr-modify/frame-optr-modify.component';
+import { FrameOptrRoleComponent } from './frame-optr-role/frame-optr-role.component';
+
+const routes: Routes = [
+  {path: 'page', component: FrameOptrPageComponent},
+];
+
+@NgModule({
+  imports: [
+    SharedModule,
+    RouterModule.forChild(routes)
+  ],
+  entryComponents: [FrameOptrCreateComponent , FrameOptrModifyComponent, FrameOptrRoleComponent],
+  declarations: [ FrameOptrPageComponent, FrameOptrCreateComponent, FrameOptrModifyComponent, FrameOptrRoleComponent],
+  exports: [
+    RouterModule
+  ]
+})
+export class FrameOptrModule {
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor