From 0c6269f2eda7a090ebd7d10298d55b7bc832297b Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 19 Jun 2021 19:41:12 -0400
Subject: trying to solve sidebar issues

---
 src/client/views/MainView.tsx | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eeb1fc95..9d7999672 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -103,7 +103,7 @@ export class MainView extends React.Component {
         }
         new InkStrokeProperties();
         this._sidebarContent.proto = undefined;
-        DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "_sidebarWidthPercent", "_width", "_height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden"]); // can play with these fields on someone else's
+        DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "showSidebar", "_sidebarWidthPercent", "_width", "_height", "width", "height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden", "nativeWidth", "_nativeWidth"]); // can play with these fields on someone else's
 
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
 
@@ -180,8 +180,8 @@ export class MainView extends React.Component {
             const targClass = targets[0].className.toString();
             if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
-                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                        thing.className === "collectionSchema-header-menuOptions"));
+                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+                    thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
             }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
-- 
cgit v1.2.3-70-g09d2


From 676b8fc85b5a12929457ff352d0e0e759f8b40ed Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 22 Jun 2021 13:39:34 -0400
Subject: added "live" flag to url parsing to override playground fields.

---
 src/client/views/Main.tsx     |  1 +
 src/client/views/MainView.tsx | 10 ++++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx
index 60327f1bf..7553c8118 100644
--- a/src/client/views/Main.tsx
+++ b/src/client/views/Main.tsx
@@ -12,6 +12,7 @@ import { LinkManager } from "../util/LinkManager";
 AssignAllExtensions();
 
 (async () => {
+    MainView.Live = window.location.search.includes("live");
     window.location.search.includes("safe") && CollectionView.SetSafeMode(true);
     const info = await CurrentUserUtils.loadCurrentUser();
     if (info.id !== "__guest__") {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9d7999672..a064f7fe8 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -68,6 +68,7 @@ const _global = (window /* browser */ || global /* node */) as any;
 @observer
 export class MainView extends React.Component {
     public static Instance: MainView;
+    public static Live: boolean = false;
     private _docBtnRef = React.createRef<HTMLDivElement>();
     @observable public LastButton: Opt<Doc>;
     @observable private _windowWidth: number = 0;
@@ -103,8 +104,9 @@ export class MainView extends React.Component {
         }
         new InkStrokeProperties();
         this._sidebarContent.proto = undefined;
-        DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "showSidebar", "_sidebarWidthPercent", "_width", "_height", "width", "height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden", "nativeWidth", "_nativeWidth"]); // can play with these fields on someone else's
-
+        if (!MainView.Live) {
+            DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "showSidebar", "_sidebarWidthPercent", "_width", "_height", "width", "height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden", "nativeWidth", "_nativeWidth"]); // can play with these fields on someone else's
+        }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
 
         const tag = document.createElement('script');
@@ -180,8 +182,8 @@ export class MainView extends React.Component {
             const targClass = targets[0].className.toString();
             if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
-                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                    thing.className === "collectionSchema-header-menuOptions"));
+                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+                        thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
             }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
-- 
cgit v1.2.3-70-g09d2


From 4fe24111c6eafc58927fcca9d8c46a5b92cc4078 Mon Sep 17 00:00:00 2001
From: Ashley Cai <ashley.lcai@gmail.com>
Date: Sat, 10 Jul 2021 00:17:09 -0700
Subject: Standardizing Colors, changing global CSS variables

---
 .VSCodeCounter/details.md                          |     4 +-
 .VSCodeCounter/results.csv                         |     4 +-
 .VSCodeCounter/results.txt                         |     4 +-
 package-lock.json                                  | 23038 ++++++++++++++++++-
 src/client/ClientRecommender.scss                  |     2 +-
 src/client/documents/Documents.ts                  |     2 +-
 src/client/util/CaptureManager.scss                |     2 +-
 src/client/util/DragManager.ts                     |     2 +-
 src/client/util/SettingsManager.scss               |     4 +-
 src/client/views/AntimodeMenu.scss                 |     2 +-
 src/client/views/ContextMenu.scss                  |    18 +-
 src/client/views/DocumentButtonBar.scss            |    12 +-
 src/client/views/DocumentDecorations.scss          |    20 +-
 src/client/views/Main.scss                         |     6 +-
 src/client/views/MainView.scss                     |     2 +-
 src/client/views/MainView.tsx                      |     6 +-
 src/client/views/PropertiesButtons.scss            |    16 +-
 src/client/views/TemplateMenu.scss                 |     6 +-
 src/client/views/animationtimeline/Keyframe.scss   |    10 +-
 src/client/views/animationtimeline/Keyframe.tsx    |     2 +-
 src/client/views/animationtimeline/Timeline.scss   |     4 +-
 .../views/animationtimeline/TimelineMenu.scss      |     6 +-
 .../views/animationtimeline/TimelineOverview.scss  |     2 +-
 src/client/views/animationtimeline/Track.scss      |     4 +-
 .../views/collections/CollectionDockingView.scss   |    16 +-
 .../views/collections/CollectionLinearView.scss    |     8 +-
 src/client/views/collections/CollectionMenu.scss   |     6 +-
 .../views/collections/CollectionSchemaCells.tsx    |     2 +-
 .../views/collections/CollectionSchemaView.scss    |    22 +-
 .../views/collections/CollectionSchemaView.tsx     |    24 +-
 .../views/collections/CollectionStackingView.scss  |    12 +-
 .../views/collections/CollectionTreeView.scss      |     8 +-
 src/client/views/collections/CollectionView.scss   |     4 +-
 src/client/views/collections/SchemaTable.tsx       |     2 +-
 src/client/views/collections/TreeView.scss         |     6 +-
 src/client/views/collections/TreeView.tsx          |     2 +-
 .../CollectionFreeFormRemoteCursors.scss           |     2 +-
 .../collectionFreeForm/CollectionFreeFormView.scss |     4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |    10 +-
 src/client/views/global/globalCssVariables.scss    |    52 +
 .../views/global/globalCssVariables.scss.d.ts      |    17 +
 src/client/views/global/globalEnums.tsx            |    19 +
 src/client/views/globalCssVariables.scss           |    56 -
 src/client/views/globalCssVariables.scss.d.ts      |    17 -
 src/client/views/linking/LinkEditor.scss           |    12 +-
 src/client/views/linking/LinkMenu.scss             |     2 +-
 src/client/views/linking/LinkMenuItem.scss         |    10 +-
 src/client/views/nodes/DocumentLinksButton.scss    |     4 +-
 src/client/views/nodes/DocumentView.scss           |     6 +-
 src/client/views/nodes/KeyValueBox.scss            |    20 +-
 src/client/views/nodes/KeyValuePair.scss           |     2 +-
 src/client/views/nodes/RadialMenu.scss             |     4 +-
 src/client/views/nodes/WebBox.scss                 |     2 +-
 .../nodes/formattedText/FormattedTextBox.scss      |     8 +-
 .../views/nodes/formattedText/RichTextMenu.scss    |     4 +-
 .../views/nodes/formattedText/TooltipTextMenu.scss |    10 +-
 src/client/views/search/CheckBox.scss              |     4 +-
 src/client/views/search/CollectionFilters.scss     |     2 +-
 src/client/views/search/IconBar.scss               |     2 +-
 src/client/views/search/IconButton.scss            |     4 +-
 src/client/views/search/IconButton.tsx             |     2 +-
 src/client/views/search/NaviconButton.scss         |     4 +-
 src/client/views/search/SearchBox.scss             |    10 +-
 src/client/views/search/SelectorContextMenu.scss   |     2 +-
 src/client/views/search/ToggleBar.scss             |     8 +-
 src/client/views/webcam/DashWebRTCVideo.scss       |     2 +-
 src/mobile/AudioUpload.scss                        |     2 +-
 src/mobile/ImageUpload.scss                        |     2 +-
 src/mobile/ImageUpload.tsx                         |     2 +-
 69 files changed, 23266 insertions(+), 331 deletions(-)
 create mode 100644 src/client/views/global/globalCssVariables.scss
 create mode 100644 src/client/views/global/globalCssVariables.scss.d.ts
 create mode 100644 src/client/views/global/globalEnums.tsx
 delete mode 100644 src/client/views/globalCssVariables.scss
 delete mode 100644 src/client/views/globalCssVariables.scss.d.ts

(limited to 'src/client/views/MainView.tsx')

diff --git a/.VSCodeCounter/details.md b/.VSCodeCounter/details.md
index 2f988953b..157c5ef33 100644
--- a/.VSCodeCounter/details.md
+++ b/.VSCodeCounter/details.md
@@ -424,8 +424,8 @@ Total : 646 files,  224911 codes, 32987 comments, 15880 blanks, all 273778 lines
 | [src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx) | TypeScript React | 51 | 0 | 5 | 56 |
 | [src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx) | TypeScript React | 51 | 0 | 5 | 56 |
 | [src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx) | TypeScript React | 92 | 0 | 9 | 101 |
-| [src/client/views/globalCssVariables.scss](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/globalCssVariables.scss) | SCSS | 30 | 10 | 3 | 43 |
-| [src/client/views/globalCssVariables.scss.d.ts](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/globalCssVariables.scss.d.ts) | TypeScript | 9 | 0 | 2 | 11 |
+| [src/client/views/global/global/globalCssVariables.scss](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/global/global/globalCssVariables.scss) | SCSS | 30 | 10 | 3 | 43 |
+| [src/client/views/global/global/globalCssVariables.scss.d.ts](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/global/global/globalCssVariables.scss.d.ts) | TypeScript | 9 | 0 | 2 | 11 |
 | [src/client/views/linking/LinkEditor.scss](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/linking/LinkEditor.scss) | SCSS | 124 | 1 | 25 | 150 |
 | [src/client/views/linking/LinkEditor.tsx](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/linking/LinkEditor.tsx) | TypeScript React | 252 | 7 | 50 | 309 |
 | [src/client/views/linking/LinkMenu.scss](file:///Users/bcz/Documents/GitHub/Dash-Web/src/client/views/linking/LinkMenu.scss) | SCSS | 40 | 0 | 13 | 53 |
diff --git a/.VSCodeCounter/results.csv b/.VSCodeCounter/results.csv
index b31bc8262..a346fa08d 100644
--- a/.VSCodeCounter/results.csv
+++ b/.VSCodeCounter/results.csv
@@ -412,8 +412,8 @@ src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx, TypeS
 src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx, TypeScript React, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 5, 56
 src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx, TypeScript React, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 0, 0, 0, 5, 56
 src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx, TypeScript React, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 9, 101
-src/client/views/globalCssVariables.scss, SCSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 10, 3, 43
-src/client/views/globalCssVariables.scss.d.ts, TypeScript, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 11
+src/client/views/global/globalCssVariables.scss, SCSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 10, 3, 43
+src/client/views/global/globalCssVariables.scss.d.ts, TypeScript, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 11
 src/client/views/linking/LinkEditor.scss, SCSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 1, 25, 150
 src/client/views/linking/LinkEditor.tsx, TypeScript React, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252, 0, 0, 0, 0, 0, 0, 7, 50, 309
 src/client/views/linking/LinkMenu.scss, SCSS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 13, 53
diff --git a/.VSCodeCounter/results.txt b/.VSCodeCounter/results.txt
index aaf54b147..c14fccb18 100644
--- a/.VSCodeCounter/results.txt
+++ b/.VSCodeCounter/results.txt
@@ -576,8 +576,8 @@ Files
 | src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx                                | TypeScript React |         51 |          0 |          5 |         56 |
 | src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx                                  | TypeScript React |         51 |          0 |          5 |         56 |
 | src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx                                      | TypeScript React |         92 |          0 |          9 |        101 |
-| src/client/views/globalCssVariables.scss                                                                    | SCSS             |         30 |         10 |          3 |         43 |
-| src/client/views/globalCssVariables.scss.d.ts                                                               | TypeScript       |          9 |          0 |          2 |         11 |
+| src/client/views/global/globalCssVariables.scss                                                                    | SCSS             |         30 |         10 |          3 |         43 |
+| src/client/views/global/globalCssVariables.scss.d.ts                                                               | TypeScript       |          9 |          0 |          2 |         11 |
 | src/client/views/linking/LinkEditor.scss                                                                    | SCSS             |        124 |          1 |         25 |        150 |
 | src/client/views/linking/LinkEditor.tsx                                                                     | TypeScript React |        252 |          7 |         50 |        309 |
 | src/client/views/linking/LinkMenu.scss                                                                      | SCSS             |         40 |          0 |         13 |         53 |
diff --git a/package-lock.json b/package-lock.json
index 3637b14ac..05e46ee09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,22928 @@
 {
     "name": "dash",
     "version": "1.0.0",
-    "lockfileVersion": 1,
+    "lockfileVersion": 2,
     "requires": true,
+    "packages": {
+        "": {
+            "name": "dash",
+            "version": "1.0.0",
+            "dependencies": {
+                "@fortawesome/fontawesome-svg-core": "^1.2.29",
+                "@fortawesome/free-brands-svg-icons": "^5.14.0",
+                "@fortawesome/free-regular-svg-icons": "^5.13.1",
+                "@fortawesome/free-solid-svg-icons": "^5.13.1",
+                "@fortawesome/react-fontawesome": "^0.1.11",
+                "@hig/flyout": "^1.2.1",
+                "@hig/theme-context": "^2.1.3",
+                "@hig/theme-data": "^2.16.1",
+                "@material-ui/core": "^4.11.0",
+                "@react-three/fiber": "^6.0.16",
+                "@types/cors": "^2.8.8",
+                "@types/d3-axis": "^2.0.0",
+                "@types/d3-color": "^2.0.1",
+                "@types/d3-scale": "^3.2.2",
+                "@types/d3-selection": "^2.0.0",
+                "@types/google-maps": "^3.2.2",
+                "@types/react-reconciler": "^0.26.1",
+                "@types/reveal": "^3.3.33",
+                "@types/three": "^0.126.2",
+                "@types/webscopeio__react-textarea-autocomplete": "^4.6.1",
+                "@webscopeio/react-textarea-autocomplete": "^4.7.0",
+                "adm-zip": "^0.4.16",
+                "archiver": "^3.1.1",
+                "array-batcher": "^1.2.3",
+                "async": "^2.6.2",
+                "axios": "^0.19.2",
+                "babel-runtime": "^6.26.0",
+                "bcrypt-nodejs": "0.0.3",
+                "bezier-curve": "^1.0.0",
+                "bluebird": "^3.7.2",
+                "body-parser": "^1.18.3",
+                "bootstrap": "^4.5.0",
+                "canvas": "^2.5.0",
+                "child_process": "^1.0.2",
+                "chrome": "^0.1.0",
+                "class-transformer": "^0.2.0",
+                "color": "^3.1.2",
+                "colors": "^1.4.0",
+                "connect-flash": "^0.1.1",
+                "connect-mongo": "^2.0.3",
+                "cookie-parser": "^1.4.4",
+                "cookie-session": "^2.0.0-rc.1",
+                "cors": "^2.8.5",
+                "depcheck": "^0.9.2",
+                "equation-editor-react": "github:bobzel/equation-editor-react#useLocally",
+                "exif": "^0.6.0",
+                "express": "^4.16.4",
+                "express-flash": "0.0.2",
+                "express-session": "^1.17.0",
+                "express-validator": "^5.3.1",
+                "expressjs": "^1.0.1",
+                "file-saver": "^2.0.2",
+                "find-in-files": "^0.5.0",
+                "fit-curve": "^0.1.7",
+                "flexlayout-react": "^0.3.11",
+                "fluent-ffmpeg": "^2.1.2",
+                "formidable": "^1.2.1",
+                "function-plot": "^1.22.7",
+                "golden-layout": "^1.5.9",
+                "google-auth-library": "^4.2.4",
+                "google-maps-react": "^2.0.6",
+                "googleapis": "^40.0.0",
+                "googlephotos": "^0.2.5",
+                "howler": "^2.2.0",
+                "html-to-image": "^0.1.0",
+                "html-to-text": "^5.1.1",
+                "i": "^0.3.6",
+                "image-data-uri": "^2.0.1",
+                "image-size": "^0.7.5",
+                "image-size-stream": "^1.1.0",
+                "js-datepicker": "^4.6.6",
+                "jsonschema": "^1.2.5",
+                "jszip": "^3.5.0",
+                "libxmljs": "^0.19.7",
+                "lodash": "^4.17.15",
+                "material-ui": "^0.20.2",
+                "mobile-detect": "^1.4.4",
+                "mobx": "^5.15.7",
+                "mobx-react": "^5.4.4",
+                "mobx-react-devtools": "^6.1.1",
+                "mobx-utils": "^5.6.1",
+                "mongodb": "^3.5.9",
+                "mongoose": "^5.9.20",
+                "node-sass": "^4.14.1",
+                "node-stream-zip": "^1.11.2",
+                "nodemailer": "^5.1.1",
+                "nodemon": "^1.19.4",
+                "normalize.css": "^8.0.1",
+                "npm": "^6.14.5",
+                "p-limit": "^2.2.0",
+                "passport": "^0.4.0",
+                "passport-google-oauth20": "^2.0.0",
+                "passport-local": "^1.0.0",
+                "pdf-parse": "^1.1.1",
+                "pdfjs": "^2.3.9",
+                "pdfjs-dist": "^2.4.456",
+                "probe-image-size": "^4.0.0",
+                "prosemirror-commands": "^1.1.3",
+                "prosemirror-dev-tools": "^3.0.1",
+                "prosemirror-find-replace": "^0.9.0",
+                "prosemirror-history": "^1.1.3",
+                "prosemirror-inputrules": "^1.1.2",
+                "prosemirror-keymap": "^1.1.4",
+                "prosemirror-model": "^1.10.0",
+                "prosemirror-schema-list": "^1.1.2",
+                "prosemirror-state": "^1.3.2",
+                "prosemirror-transform": "^1.2.6",
+                "prosemirror-view": "^1.15.0",
+                "pug": "^2.0.4",
+                "puppeteer": "^3.3.0",
+                "query-string": "^6.13.1",
+                "raw-loader": "^1.0.0",
+                "rc-switch": "^1.9.0",
+                "react": "^16.12.0",
+                "react-audio-waveform": "0.0.5",
+                "react-autosuggest": "^9.4.3",
+                "react-beautiful-dnd": "^13.0.0",
+                "react-color": "^2.18.1",
+                "react-compound-slider": "^2.5.0",
+                "react-datepicker": "^3.0.0",
+                "react-dom": "^16.12.0",
+                "react-grid-layout": "^0.18.3",
+                "react-image-lightbox-with-rotate": "^5.1.1",
+                "react-jsx-parser": "^1.25.1",
+                "react-loading": "^2.0.3",
+                "react-measure": "^2.2.4",
+                "react-resizable": "^1.10.1",
+                "react-resizable-rotatable-draggable": "^0.2.0",
+                "react-reveal": "^1.2.2",
+                "react-select": "^3.1.0",
+                "react-table": "^6.11.5",
+                "readline": "^1.3.0",
+                "request": "^2.88.0",
+                "request-promise": "^4.2.5",
+                "reveal.js": "^4.0.2",
+                "rimraf": "^3.0.0",
+                "serializr": "^1.5.4",
+                "sharp": "^0.23.4",
+                "shelljs": "^0.8.3",
+                "socket.io": "^2.3.0",
+                "socket.io-client": "^2.3.0",
+                "solr-node": "^1.2.1",
+                "standard-http-error": "^2.0.1",
+                "styled-components": "^4.4.1",
+                "textarea-caret": "^3.1.0",
+                "three": "^0.127.0",
+                "translate-google-api": "^1.0.4",
+                "typescript-collections": "^1.3.3",
+                "typescript-language-server": "^0.4.0",
+                "url-loader": "^1.1.2",
+                "uuid": "^3.4.0",
+                "valid-url": "^1.0.9",
+                "web-request": "^1.0.7",
+                "webrtc-adapter": "^7.6.3",
+                "wikijs": "^6.0.1",
+                "words-to-numbers": "^1.5.1",
+                "xoauth2": "^1.2.0",
+                "xregexp": "^4.3.0"
+            },
+            "devDependencies": {
+                "@types/adm-zip": "^0.4.32",
+                "@types/animejs": "^2.0.2",
+                "@types/archiver": "^3.0.0",
+                "@types/async": "^2.4.1",
+                "@types/bcrypt-nodejs": "0.0.30",
+                "@types/bluebird": "^3.5.32",
+                "@types/body-parser": "^1.17.1",
+                "@types/chai": "^4.2.7",
+                "@types/color": "^3.0.1",
+                "@types/connect-flash": "0.0.34",
+                "@types/cookie-parser": "^1.4.2",
+                "@types/cookie-session": "^2.0.41",
+                "@types/dotenv": "^6.1.1",
+                "@types/exif": "^0.6.1",
+                "@types/express": "^4.17.2",
+                "@types/express-flash": "0.0.0",
+                "@types/express-session": "^1.15.16",
+                "@types/express-validator": "^3.0.0",
+                "@types/file-saver": "^2.0.1",
+                "@types/formidable": "^1.0.31",
+                "@types/google-maps-react": "^2.0.5",
+                "@types/jquery": "^3.5.0",
+                "@types/libxmljs": "^0.18.5",
+                "@types/lodash": "^4.14.157",
+                "@types/mobile-detect": "^1.3.4",
+                "@types/mocha": "^5.2.6",
+                "@types/mongodb": "^3.5.25",
+                "@types/mongoose": "^5.7.28",
+                "@types/node": "^10.17.26",
+                "@types/nodemailer": "^4.6.6",
+                "@types/passport": "^1.0.2",
+                "@types/passport-google-oauth20": "^2.0.3",
+                "@types/passport-local": "^1.0.33",
+                "@types/pdfjs-dist": "^2.1.4",
+                "@types/prosemirror-commands": "^1.0.1",
+                "@types/prosemirror-dev-tools": "^2.1.0",
+                "@types/prosemirror-history": "^1.0.1",
+                "@types/prosemirror-inputrules": "^1.0.2",
+                "@types/prosemirror-keymap": "^1.0.2",
+                "@types/prosemirror-menu": "^1.0.2",
+                "@types/prosemirror-model": "^1.7.0",
+                "@types/prosemirror-schema-list": "^1.0.1",
+                "@types/prosemirror-state": "^1.2.4",
+                "@types/prosemirror-transform": "^1.1.1",
+                "@types/prosemirror-view": "^1.11.2",
+                "@types/rc-switch": "^1.9.0",
+                "@types/react": "^16.9.41",
+                "@types/react-autosuggest": "^9.3.14",
+                "@types/react-color": "^2.17.4",
+                "@types/react-datepicker": "^3.0.2",
+                "@types/react-dom": "^16.9.8",
+                "@types/react-grid-layout": "^0.17.1",
+                "@types/react-measure": "^2.0.6",
+                "@types/react-select": "^3.0.13",
+                "@types/react-table": "^6.8.6",
+                "@types/request": "^2.48.5",
+                "@types/request-promise": "^4.1.45",
+                "@types/rimraf": "^2.0.3",
+                "@types/sharp": "^0.23.1",
+                "@types/shelljs": "^0.8.8",
+                "@types/socket.io": "^2.1.8",
+                "@types/socket.io-client": "^1.4.33",
+                "@types/typescript": "^2.0.0",
+                "@types/uuid": "^3.4.6",
+                "@types/valid-url": "^1.0.3",
+                "@types/webpack": "^4.41.27",
+                "@types/webpack-dev-middleware": "^2.0.7",
+                "@types/webpack-hot-middleware": "^2.25.4",
+                "@types/xregexp": "^4.3.0",
+                "@types/youtube": "0.0.39",
+                "awesome-typescript-loader": "^5.2.1",
+                "chai": "^4.2.0",
+                "copy-webpack-plugin": "^4.6.0",
+                "cross-env": "^5.2.1",
+                "css-loader": "^2.1.1",
+                "dotenv": "^8.2.0",
+                "file-loader": "^3.0.1",
+                "fork-ts-checker-webpack-plugin": "^1.6.0",
+                "jsdom": "^15.2.1",
+                "mocha": "^5.2.0",
+                "sass-loader": "^7.3.1",
+                "scss-loader": "0.0.1",
+                "style-loader": "^0.23.1",
+                "ts-loader": "^5.3.3",
+                "ts-node": "^7.0.1",
+                "ts-node-dev": "^1.0.0-pre.49",
+                "tslint": "^5.20.1",
+                "tslint-loader": "^3.6.0",
+                "typescript": "^3.9.9",
+                "webpack": "^4.46.0",
+                "webpack-cli": "^3.3.12",
+                "webpack-dev-middleware": "^3.7.3",
+                "webpack-dev-server": "^3.11.0",
+                "webpack-hot-middleware": "^2.24.3"
+            }
+        },
+        "node_modules/@babel/code-frame": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+            "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+            "dependencies": {
+                "@babel/highlight": "^7.8.3"
+            }
+        },
+        "node_modules/@babel/generator": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz",
+            "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==",
+            "dependencies": {
+                "@babel/types": "^7.9.6",
+                "jsesc": "^2.5.1",
+                "lodash": "^4.17.13",
+                "source-map": "^0.5.0"
+            }
+        },
+        "node_modules/@babel/generator/node_modules/@babel/types": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+            "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.9.5",
+                "lodash": "^4.17.13",
+                "to-fast-properties": "^2.0.0"
+            }
+        },
+        "node_modules/@babel/helper-annotate-as-pure": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz",
+            "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==",
+            "dependencies": {
+                "@babel/types": "^7.10.4"
+            }
+        },
+        "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/helper-validator-identifier": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
+            "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw=="
+        },
+        "node_modules/@babel/helper-annotate-as-pure/node_modules/@babel/types": {
+            "version": "7.10.5",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz",
+            "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.10.4",
+                "lodash": "^4.17.19",
+                "to-fast-properties": "^2.0.0"
+            }
+        },
+        "node_modules/@babel/helper-annotate-as-pure/node_modules/lodash": {
+            "version": "4.17.19",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
+            "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ=="
+        },
+        "node_modules/@babel/helper-function-name": {
+            "version": "7.9.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz",
+            "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==",
+            "dependencies": {
+                "@babel/helper-get-function-arity": "^7.8.3",
+                "@babel/template": "^7.8.3",
+                "@babel/types": "^7.9.5"
+            }
+        },
+        "node_modules/@babel/helper-get-function-arity": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+            "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+            "dependencies": {
+                "@babel/types": "^7.8.3"
+            }
+        },
+        "node_modules/@babel/helper-module-imports": {
+            "version": "7.10.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz",
+            "integrity": "sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w==",
+            "dependencies": {
+                "@babel/types": "^7.10.3"
+            }
+        },
+        "node_modules/@babel/helper-module-imports/node_modules/@babel/helper-validator-identifier": {
+            "version": "7.10.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz",
+            "integrity": "sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw=="
+        },
+        "node_modules/@babel/helper-module-imports/node_modules/@babel/types": {
+            "version": "7.10.3",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.3.tgz",
+            "integrity": "sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.10.3",
+                "lodash": "^4.17.13",
+                "to-fast-properties": "^2.0.0"
+            }
+        },
+        "node_modules/@babel/helper-split-export-declaration": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+            "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+            "dependencies": {
+                "@babel/types": "^7.8.3"
+            }
+        },
+        "node_modules/@babel/helper-validator-identifier": {
+            "version": "7.9.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
+            "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g=="
+        },
+        "node_modules/@babel/highlight": {
+            "version": "7.9.0",
+            "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+            "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.9.0",
+                "chalk": "^2.0.0",
+                "js-tokens": "^4.0.0"
+            }
+        },
+        "node_modules/@babel/parser": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz",
+            "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==",
+            "bin": {
+                "parser": "bin/babel-parser.js"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/@babel/runtime": {
+            "version": "7.9.2",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
+            "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==",
+            "dependencies": {
+                "regenerator-runtime": "^0.13.4"
+            }
+        },
+        "node_modules/@babel/runtime-corejs3": {
+            "version": "7.9.2",
+            "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz",
+            "integrity": "sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA==",
+            "dependencies": {
+                "core-js-pure": "^3.0.0",
+                "regenerator-runtime": "^0.13.4"
+            }
+        },
+        "node_modules/@babel/template": {
+            "version": "7.8.6",
+            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
+            "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+            "dependencies": {
+                "@babel/code-frame": "^7.8.3",
+                "@babel/parser": "^7.8.6",
+                "@babel/types": "^7.8.6"
+            }
+        },
+        "node_modules/@babel/traverse": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz",
+            "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==",
+            "dependencies": {
+                "@babel/code-frame": "^7.8.3",
+                "@babel/generator": "^7.9.6",
+                "@babel/helper-function-name": "^7.9.5",
+                "@babel/helper-split-export-declaration": "^7.8.3",
+                "@babel/parser": "^7.9.6",
+                "@babel/types": "^7.9.6",
+                "debug": "^4.1.0",
+                "globals": "^11.1.0",
+                "lodash": "^4.17.13"
+            }
+        },
+        "node_modules/@babel/traverse/node_modules/@babel/types": {
+            "version": "7.9.6",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz",
+            "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.9.5",
+                "lodash": "^4.17.13",
+                "to-fast-properties": "^2.0.0"
+            }
+        },
+        "node_modules/@babel/traverse/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/@babel/types": {
+            "version": "7.9.5",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz",
+            "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==",
+            "dependencies": {
+                "@babel/helper-validator-identifier": "^7.9.5",
+                "lodash": "^4.17.13",
+                "to-fast-properties": "^2.0.0"
+            }
+        },
+        "node_modules/@emotion/cache": {
+            "version": "10.0.29",
+            "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz",
+            "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==",
+            "dependencies": {
+                "@emotion/sheet": "0.9.4",
+                "@emotion/stylis": "0.8.5",
+                "@emotion/utils": "0.11.3",
+                "@emotion/weak-memoize": "0.2.5"
+            }
+        },
+        "node_modules/@emotion/core": {
+            "version": "10.0.28",
+            "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz",
+            "integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==",
+            "dependencies": {
+                "@babel/runtime": "^7.5.5",
+                "@emotion/cache": "^10.0.27",
+                "@emotion/css": "^10.0.27",
+                "@emotion/serialize": "^0.11.15",
+                "@emotion/sheet": "0.9.4",
+                "@emotion/utils": "0.11.3"
+            }
+        },
+        "node_modules/@emotion/css": {
+            "version": "10.0.27",
+            "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz",
+            "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==",
+            "dependencies": {
+                "@emotion/serialize": "^0.11.15",
+                "@emotion/utils": "0.11.3",
+                "babel-plugin-emotion": "^10.0.27"
+            }
+        },
+        "node_modules/@emotion/hash": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+            "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
+        },
+        "node_modules/@emotion/is-prop-valid": {
+            "version": "0.8.8",
+            "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+            "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+            "dependencies": {
+                "@emotion/memoize": "0.7.4"
+            }
+        },
+        "node_modules/@emotion/memoize": {
+            "version": "0.7.4",
+            "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+            "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
+        },
+        "node_modules/@emotion/serialize": {
+            "version": "0.11.16",
+            "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz",
+            "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==",
+            "dependencies": {
+                "@emotion/hash": "0.8.0",
+                "@emotion/memoize": "0.7.4",
+                "@emotion/unitless": "0.7.5",
+                "@emotion/utils": "0.11.3",
+                "csstype": "^2.5.7"
+            }
+        },
+        "node_modules/@emotion/sheet": {
+            "version": "0.9.4",
+            "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz",
+            "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA=="
+        },
+        "node_modules/@emotion/styled": {
+            "version": "10.0.27",
+            "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-10.0.27.tgz",
+            "integrity": "sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q==",
+            "dependencies": {
+                "@emotion/styled-base": "^10.0.27",
+                "babel-plugin-emotion": "^10.0.27"
+            }
+        },
+        "node_modules/@emotion/styled-base": {
+            "version": "10.0.31",
+            "resolved": "https://registry.npmjs.org/@emotion/styled-base/-/styled-base-10.0.31.tgz",
+            "integrity": "sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ==",
+            "dependencies": {
+                "@babel/runtime": "^7.5.5",
+                "@emotion/is-prop-valid": "0.8.8",
+                "@emotion/serialize": "^0.11.15",
+                "@emotion/utils": "0.11.3"
+            }
+        },
+        "node_modules/@emotion/stylis": {
+            "version": "0.8.5",
+            "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+            "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
+        },
+        "node_modules/@emotion/unitless": {
+            "version": "0.7.5",
+            "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz",
+            "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+        },
+        "node_modules/@emotion/utils": {
+            "version": "0.11.3",
+            "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz",
+            "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw=="
+        },
+        "node_modules/@emotion/weak-memoize": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz",
+            "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA=="
+        },
+        "node_modules/@fortawesome/fontawesome-common-types": {
+            "version": "0.2.29",
+            "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.29.tgz",
+            "integrity": "sha512-cY+QfDTbZ7XVxzx7jxbC98Oxr/zc7R2QpTLqTxqlfyXDrAJjzi/xUIqAUsygELB62JIrbsWxtSRhayKFkGI7MA==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/fontawesome-svg-core": {
+            "version": "1.2.29",
+            "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.29.tgz",
+            "integrity": "sha512-xmPmP2t8qrdo8RyKihTkGb09RnZoc+7HFBCnr0/6ZhStdGDSLeEd7ajV181+2W29NWIFfylO13rU+s3fpy3cnA==",
+            "dependencies": {
+                "@fortawesome/fontawesome-common-types": "^0.2.29"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/free-brands-svg-icons": {
+            "version": "5.14.0",
+            "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.14.0.tgz",
+            "integrity": "sha512-WsqPFTvJFI7MYkcy0jeFE2zY+blC4OrnB9MJOcn1NxRXT/sSfEEhrI7CwzIkiYajLiVDBKWeErYOvpsMeodmCQ==",
+            "dependencies": {
+                "@fortawesome/fontawesome-common-types": "^0.2.30"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/free-brands-svg-icons/node_modules/@fortawesome/fontawesome-common-types": {
+            "version": "0.2.30",
+            "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz",
+            "integrity": "sha512-TsRwpTuKwFNiPhk1UfKgw7zNPeV5RhNp2Uw3pws+9gDAkPGKrtjR1y2lI3SYn7+YzyfuNknflpBA1LRKjt7hMg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/free-regular-svg-icons": {
+            "version": "5.13.1",
+            "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.13.1.tgz",
+            "integrity": "sha512-sSeaqqmv2ovA5LKcrbh3VnEDZHVhaxijWKm4R0AdT0eG21pgxNsJbStD8lW9z6bgSuWXRNHhbhOmARuRCLS8tw==",
+            "dependencies": {
+                "@fortawesome/fontawesome-common-types": "^0.2.29"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/free-solid-svg-icons": {
+            "version": "5.13.1",
+            "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.13.1.tgz",
+            "integrity": "sha512-LQH/0L1p4+rqtoSHa9qFYR84hpuRZKqaQ41cfBQx8b68p21zoWSekTAeA54I/2x9VlCHDLFlG74Nmdg4iTPQOg==",
+            "dependencies": {
+                "@fortawesome/fontawesome-common-types": "^0.2.29"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/@fortawesome/react-fontawesome": {
+            "version": "0.1.11",
+            "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.11.tgz",
+            "integrity": "sha512-sClfojasRifQKI0OPqTy8Ln8iIhnxR/Pv/hukBhWnBz9kQRmqi6JSH3nghlhAY7SUeIIM7B5/D2G8WjX0iepVg==",
+            "dependencies": {
+                "prop-types": "^15.7.2"
+            }
+        },
+        "node_modules/@hig/flyout": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@hig/flyout/-/flyout-1.2.1.tgz",
+            "integrity": "sha512-oNybmhStyMmEC07DPsjMZg4Dgm65X7Jcp2nDFR9zZghVof/1C3WJtJvdouVgqx7BJw2IedVj8CUGoPuoll/0IQ==",
+            "dependencies": {
+                "@hig/utils": "^0.4.0",
+                "emotion": "^10.0.0",
+                "prop-types": "^15.7.1",
+                "react-transition-group": "^2.3.1"
+            }
+        },
+        "node_modules/@hig/theme-context": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.3.tgz",
+            "integrity": "sha512-c0Ju+Z8C532ZZtjwOLzN+XeO+pL3kqUawu6ZG3J084MH5RM9W8JCKyMf4D9Qr38jFWoiX6u8yiSxxjV/mz9Sqw==",
+            "dependencies": {
+                "create-react-context": "^0.2.3",
+                "prop-types": "^15.6.1"
+            }
+        },
+        "node_modules/@hig/theme-data": {
+            "version": "2.16.1",
+            "resolved": "https://registry.npmjs.org/@hig/theme-data/-/theme-data-2.16.1.tgz",
+            "integrity": "sha512-3nBnzRqYyc6ejoCgA+zBjQGqe6LAXlcemTs0257E5bWu/JyZe8YyOLN+psq2zyjF+FUk35p38wWNPyaOcPnhvw==",
+            "dependencies": {
+                "tinycolor2": "^1.4.1"
+            }
+        },
+        "node_modules/@hig/utils": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/@hig/utils/-/utils-0.4.0.tgz",
+            "integrity": "sha512-EQnMGZKdPh9UJaBUKLKXp92sSoCo+PTpgrGNd8q+71uRFdD0udMu/+yeVekTEtNOJcCk1gnKfyg1rRvIbTcpRw==",
+            "dependencies": {
+                "emotion": "^10.0.0",
+                "lodash.memoize": "^4.1.2"
+            }
+        },
+        "node_modules/@icons/material": {
+            "version": "0.2.4",
+            "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
+            "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
+        },
+        "node_modules/@log4js-node/log4js-api": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
+            "integrity": "sha512-6SJfx949YEWooh/CUPpJ+F491y4BYJmknz4hUN1+RHvKoUEynKbRmhnwbk/VLmh4OthLLDNCyWXfbh4DG1cTXA=="
+        },
+        "node_modules/@material-ui/core": {
+            "version": "4.11.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.11.0.tgz",
+            "integrity": "sha512-bYo9uIub8wGhZySHqLQ833zi4ZML+XCBE1XwJ8EuUVSpTWWG57Pm+YugQToJNFsEyiKFhPh8DPD0bgupz8n01g==",
+            "dependencies": {
+                "@babel/runtime": "^7.4.4",
+                "@material-ui/styles": "^4.10.0",
+                "@material-ui/system": "^4.9.14",
+                "@material-ui/types": "^5.1.0",
+                "@material-ui/utils": "^4.10.2",
+                "@types/react-transition-group": "^4.2.0",
+                "clsx": "^1.0.4",
+                "hoist-non-react-statics": "^3.3.2",
+                "popper.js": "1.16.1-lts",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.8.0",
+                "react-transition-group": "^4.4.0"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/@material-ui/core/node_modules/dom-helpers": {
+            "version": "5.1.4",
+            "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+            "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+            "dependencies": {
+                "@babel/runtime": "^7.8.7",
+                "csstype": "^2.6.7"
+            }
+        },
+        "node_modules/@material-ui/core/node_modules/popper.js": {
+            "version": "1.16.1-lts",
+            "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+            "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+        },
+        "node_modules/@material-ui/core/node_modules/react-transition-group": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+            "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+            "dependencies": {
+                "@babel/runtime": "^7.5.5",
+                "dom-helpers": "^5.0.1",
+                "loose-envify": "^1.4.0",
+                "prop-types": "^15.6.2"
+            }
+        },
+        "node_modules/@material-ui/styles": {
+            "version": "4.10.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
+            "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==",
+            "dependencies": {
+                "@babel/runtime": "^7.4.4",
+                "@emotion/hash": "^0.8.0",
+                "@material-ui/types": "^5.1.0",
+                "@material-ui/utils": "^4.9.6",
+                "clsx": "^1.0.4",
+                "csstype": "^2.5.2",
+                "hoist-non-react-statics": "^3.3.2",
+                "jss": "^10.0.3",
+                "jss-plugin-camel-case": "^10.0.3",
+                "jss-plugin-default-unit": "^10.0.3",
+                "jss-plugin-global": "^10.0.3",
+                "jss-plugin-nested": "^10.0.3",
+                "jss-plugin-props-sort": "^10.0.3",
+                "jss-plugin-rule-value-function": "^10.0.3",
+                "jss-plugin-vendor-prefixer": "^10.0.3",
+                "prop-types": "^15.7.2"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/@material-ui/system": {
+            "version": "4.9.14",
+            "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz",
+            "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==",
+            "dependencies": {
+                "@babel/runtime": "^7.4.4",
+                "@material-ui/utils": "^4.9.6",
+                "csstype": "^2.5.2",
+                "prop-types": "^15.7.2"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/@material-ui/types": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+            "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
+        },
+        "node_modules/@material-ui/utils": {
+            "version": "4.10.2",
+            "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.10.2.tgz",
+            "integrity": "sha512-eg29v74P7W5r6a4tWWDAAfZldXIzfyO1am2fIsC39hdUUHm/33k6pGOKPbgDjg/U/4ifmgAePy/1OjkKN6rFRw==",
+            "dependencies": {
+                "@babel/runtime": "^7.4.4",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.8.0"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/@react-three/fiber": {
+            "version": "6.0.16",
+            "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-6.0.16.tgz",
+            "integrity": "sha512-oKMYNJOd5t+V4o18aRMhaRhcDQ1NeeCDy52yJvXpu7zrsR04YZtXD4RacW0FDH0KnwkOLDst95LCCphm3Thk/A==",
+            "dependencies": {
+                "@babel/runtime": "^7.13.10",
+                "react-merge-refs": "^1.1.0",
+                "react-reconciler": "^0.26.2",
+                "react-three-fiber": "0.0.0-deprecated",
+                "react-use-measure": "^2.0.4",
+                "resize-observer-polyfill": "^1.5.1",
+                "scheduler": "^0.20.2",
+                "use-asset": "^1.0.4",
+                "utility-types": "^3.10.0",
+                "zustand": "^3.3.3"
+            }
+        },
+        "node_modules/@react-three/fiber/node_modules/@babel/runtime": {
+            "version": "7.13.17",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.17.tgz",
+            "integrity": "sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==",
+            "dependencies": {
+                "regenerator-runtime": "^0.13.4"
+            }
+        },
+        "node_modules/@react-three/fiber/node_modules/scheduler": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+            "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1"
+            }
+        },
+        "node_modules/@rkusa/linebreak": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/@rkusa/linebreak/-/linebreak-1.0.0.tgz",
+            "integrity": "sha512-yCSm87XA1aYMgfcABSxcIkk3JtCw3AihNceHY+DnZGLvVP/g2z3UWZbi0xIoYpZWAJEVPr5Zt3QE37Q80wF1pA==",
+            "dependencies": {
+                "unicode-trie": "^0.3.0"
+            }
+        },
+        "node_modules/@types/adm-zip": {
+            "version": "0.4.33",
+            "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.33.tgz",
+            "integrity": "sha512-WM0DCWFLjXtddl0fu0+iN2ZF+qz8RF9RddG5OSy/S90AQz01Fu8lHn/3oTIZDxvG8gVcnBLAHMHOdBLbV6m6Mw==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/animejs": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/@types/animejs/-/animejs-2.0.2.tgz",
+            "integrity": "sha512-ACymFQ5qgSrZNR1Fqjk7Wv9gH6dFgejn2gpLkkceWxTKzivRJsshX4xhBVALgvF79gUdXiMCRIdusN728XpeGA==",
+            "dev": true
+        },
+        "node_modules/@types/anymatch": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
+            "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
+            "dev": true
+        },
+        "node_modules/@types/archiver": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-3.1.0.tgz",
+            "integrity": "sha512-nTvHwgWONL+iXG+9CX+gnQ/tTOV+qucAjwpXqeUn4OCRMxP42T29FFP/7XaOo0EqqO3TlENhObeZEe7RUJAriw==",
+            "dev": true,
+            "dependencies": {
+                "@types/glob": "*"
+            }
+        },
+        "node_modules/@types/assert": {
+            "version": "1.5.4",
+            "resolved": "https://registry.npmjs.org/@types/assert/-/assert-1.5.4.tgz",
+            "integrity": "sha512-CaFVW21Ulu0J9sUaEWJjwmhkDkeoxa4fniVSERzZC13sU9v8NNM2lMlkfZZv60j47D+qDt0Lyo8skVP3CTXUdA=="
+        },
+        "node_modules/@types/async": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/@types/async/-/async-2.4.2.tgz",
+            "integrity": "sha512-bWBbC7VG2jdjbgZMX0qpds8U/3h3anfIqE81L8jmVrgFZw/urEDnBA78ymGGKTTK6ciBXmmJ/xlok+Re41S8ww==",
+            "dev": true
+        },
+        "node_modules/@types/babel-types": {
+            "version": "7.0.7",
+            "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz",
+            "integrity": "sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ=="
+        },
+        "node_modules/@types/babylon": {
+            "version": "6.16.5",
+            "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
+            "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
+            "dependencies": {
+                "@types/babel-types": "*"
+            }
+        },
+        "node_modules/@types/bcrypt-nodejs": {
+            "version": "0.0.30",
+            "resolved": "https://registry.npmjs.org/@types/bcrypt-nodejs/-/bcrypt-nodejs-0.0.30.tgz",
+            "integrity": "sha1-TN2WtJKTs5MhIuS34pVD415rrlg=",
+            "dev": true
+        },
+        "node_modules/@types/bluebird": {
+            "version": "3.5.32",
+            "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.32.tgz",
+            "integrity": "sha512-dIOxFfI0C+jz89g6lQ+TqhGgPQ0MxSnh/E4xuC0blhFtyW269+mPG5QeLgbdwst/LvdP8o1y0o/Gz5EHXLec/g==",
+            "dev": true
+        },
+        "node_modules/@types/body-parser": {
+            "version": "1.19.0",
+            "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
+            "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+            "dependencies": {
+                "@types/connect": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/bson": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.2.tgz",
+            "integrity": "sha512-+uWmsejEHfmSjyyM/LkrP0orfE2m5Mx9Xel4tXNeqi1ldK5XMQcDsFkBmLDtuyKUbxj2jGDo0H240fbCRJZo7Q==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/caseless": {
+            "version": "0.12.2",
+            "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
+            "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
+            "dev": true
+        },
+        "node_modules/@types/chai": {
+            "version": "4.2.11",
+            "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz",
+            "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==",
+            "dev": true
+        },
+        "node_modules/@types/color": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz",
+            "integrity": "sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA==",
+            "dev": true,
+            "dependencies": {
+                "@types/color-convert": "*"
+            }
+        },
+        "node_modules/@types/color-convert": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-1.9.0.tgz",
+            "integrity": "sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg==",
+            "dev": true,
+            "dependencies": {
+                "@types/color-name": "*"
+            }
+        },
+        "node_modules/@types/color-name": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
+            "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
+        },
+        "node_modules/@types/connect": {
+            "version": "3.4.33",
+            "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz",
+            "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==",
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/connect-flash": {
+            "version": "0.0.34",
+            "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.34.tgz",
+            "integrity": "sha512-QC93TwnTZ0sk//bfT81o7U4GOedbOZAcgvqi0v1vJqCESC8tqIVnhzB1CHiAUBUWFjoxG5JQF0TYaNa6DMb6Ig==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*"
+            }
+        },
+        "node_modules/@types/cookie-parser": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
+            "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*"
+            }
+        },
+        "node_modules/@types/cookie-session": {
+            "version": "2.0.41",
+            "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.41.tgz",
+            "integrity": "sha512-Ytd7zWY3WvC7TP9rKVjlnYHus8Hq+lJuioHOtKJ7dXg2Nt+O+9UpelygYy5Eb67QQN92HPO5qEG0vnmAlqRLLw==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/keygrip": "*"
+            }
+        },
+        "node_modules/@types/cors": {
+            "version": "2.8.8",
+            "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.8.tgz",
+            "integrity": "sha512-fO3gf3DxU2Trcbr75O7obVndW/X5k8rJNZkLXlQWStTHhP71PkRqjwPIEI0yMnJdg9R9OasjU+Bsr+Hr1xy/0w==",
+            "dependencies": {
+                "@types/express": "*"
+            }
+        },
+        "node_modules/@types/d3-axis": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-2.0.0.tgz",
+            "integrity": "sha512-gUdlEwGBLl3tXGiBnBNmNzph9W3bCfa4tBgWZD60Z1eDQKTY4zyCAcZ3LksignGfKawYatmDYcBdjJ5h/54sqA==",
+            "dependencies": {
+                "@types/d3-selection": "*"
+            }
+        },
+        "node_modules/@types/d3-color": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.1.tgz",
+            "integrity": "sha512-u7LTCL7RnaavFSmob2rIAJLNwu50i6gFwY9cHFr80BrQURYQBRkJ+Yv47nA3Fm7FeRhdWTiVTeqvSeOuMAOzBQ=="
+        },
+        "node_modules/@types/d3-scale": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.2.2.tgz",
+            "integrity": "sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ==",
+            "dependencies": {
+                "@types/d3-time": "*"
+            }
+        },
+        "node_modules/@types/d3-selection": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.0.tgz",
+            "integrity": "sha512-EF0lWZ4tg7oDFg4YQFlbOU3936e3a9UmoQ2IXlBy1+cv2c2Pv7knhKUzGlH5Hq2sF/KeDTH1amiRPey2rrLMQA=="
+        },
+        "node_modules/@types/d3-time": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.0.0.tgz",
+            "integrity": "sha512-Abz8bTzy8UWDeYs9pCa3D37i29EWDjNTjemdk0ei1ApYVNqulYlGUKip/jLOpogkPSsPz/GvZCYiC7MFlEk0iQ=="
+        },
+        "node_modules/@types/dotenv": {
+            "version": "6.1.1",
+            "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
+            "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/engine.io": {
+            "version": "3.1.4",
+            "resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.4.tgz",
+            "integrity": "sha512-98rXVukLD6/ozrQ2O80NAlWDGA4INg+tqsEReWJldqyi2fulC9V7Use/n28SWgROXKm6003ycWV4gZHoF8GA6w==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@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
+        },
+        "node_modules/@types/exif": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/@types/exif/-/exif-0.6.1.tgz",
+            "integrity": "sha512-hw4RQiuu+L//CpZ1vL3EopGY3L6mGvPFK2CpWCmvlwUAquvosWfCU3ZFq9jsZ2rmIun71XJm2I2KPx7tT1VuxA==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/express": {
+            "version": "4.17.6",
+            "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz",
+            "integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==",
+            "dependencies": {
+                "@types/body-parser": "*",
+                "@types/express-serve-static-core": "*",
+                "@types/qs": "*",
+                "@types/serve-static": "*"
+            }
+        },
+        "node_modules/@types/express-flash": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.0.tgz",
+            "integrity": "sha512-zs1xXRIZOjghUBriJPSnhPmfDpqf/EQxT21ggi/9XZ9/RHYrUi+5vK2jnQrP2pD1abbuZvm7owLICiNCLBQzEQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/connect-flash": "*",
+                "@types/express": "*"
+            }
+        },
+        "node_modules/@types/express-serve-static-core": {
+            "version": "4.17.5",
+            "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz",
+            "integrity": "sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw==",
+            "dependencies": {
+                "@types/node": "*",
+                "@types/range-parser": "*"
+            }
+        },
+        "node_modules/@types/express-session": {
+            "version": "1.17.0",
+            "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.0.tgz",
+            "integrity": "sha512-OQEHeBFE1UhChVIBhRh9qElHUvTp4BzKKHxMDkGHT7WuYk5eL93hPG7D8YAIkoBSbhNEY0RjreF15zn+U0eLjA==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/express-validator": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/@types/express-validator/-/express-validator-3.0.0.tgz",
+            "integrity": "sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ==",
+            "dev": true,
+            "dependencies": {
+                "express-validator": "*"
+            }
+        },
+        "node_modules/@types/file-saver": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz",
+            "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==",
+            "dev": true
+        },
+        "node_modules/@types/formidable": {
+            "version": "1.0.31",
+            "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz",
+            "integrity": "sha512-dIhM5t8lRP0oWe2HF8MuPvdd1TpPTjhDMAqemcq6oIZQCBQTovhBAdTQ5L5veJB4pdQChadmHuxtB0YzqvfU3Q==",
+            "dev": true,
+            "dependencies": {
+                "@types/events": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@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,
+            "dependencies": {
+                "@types/events": "*",
+                "@types/minimatch": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/google-maps": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/@types/google-maps/-/google-maps-3.2.2.tgz",
+            "integrity": "sha512-/XPVfS28VzUdE/HlmBRoe5ii1nNMyWujyRfRY08bD/JgmPlWSiY8enB2dqTe9mlc3kULq7LfFa1wcupM+lQfqA==",
+            "dependencies": {
+                "@types/googlemaps": "*"
+            }
+        },
+        "node_modules/@types/google-maps-react": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@types/google-maps-react/-/google-maps-react-2.0.5.tgz",
+            "integrity": "sha512-qcsYlHiNH169Vf7jmkEwbzBDqBfqqzYkTgK1vL7qkWVZI04wFESADYVITuQunrZ9swY/SG+tTWUIXMlY4W8byw==",
+            "dev": true,
+            "dependencies": {
+                "google-maps-react": "*"
+            }
+        },
+        "node_modules/@types/googlemaps": {
+            "version": "3.39.8",
+            "resolved": "https://registry.npmjs.org/@types/googlemaps/-/googlemaps-3.39.8.tgz",
+            "integrity": "sha512-z03u79t1v8QIktoUXypWD06Fzl499/hA162hurA+eCDlWXxFynuU+hMZIaferILF5Gzr4PMX1ShHszT666sUHQ=="
+        },
+        "node_modules/@types/jquery": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.0.tgz",
+            "integrity": "sha512-C7qQUjpMWDUNYQRTXsP5nbYYwCwwgy84yPgoTT7fPN69NH92wLeCtFaMsWeolJD1AF/6uQw3pYt62rzv83sMmw==",
+            "dev": true,
+            "dependencies": {
+                "@types/sizzle": "*"
+            }
+        },
+        "node_modules/@types/keygrip": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
+            "integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==",
+            "dev": true
+        },
+        "node_modules/@types/libxmljs": {
+            "version": "0.18.6",
+            "resolved": "https://registry.npmjs.org/@types/libxmljs/-/libxmljs-0.18.6.tgz",
+            "integrity": "sha512-xVUs71CwL5wYYfx5oH344DYWdoE2hVWlnRxlXFYyA8BcueN+Ey/h4FyhzEikbIJSXBKyPpJKhGu5c3NOx15nww==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/lodash": {
+            "version": "4.14.157",
+            "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.157.tgz",
+            "integrity": "sha512-Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiVQ==",
+            "dev": true
+        },
+        "node_modules/@types/memory-fs": {
+            "version": "0.3.3",
+            "resolved": "https://registry.npmjs.org/@types/memory-fs/-/memory-fs-0.3.3.tgz",
+            "integrity": "sha512-rLEYzl1xODshz+Lm+YX8NYws8Xw7/qcYbQInMkotl96VpLZmUvoCfYYGxfajMSiugANV02QO5Fc+R98KKeE4gQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/mime": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz",
+            "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw=="
+        },
+        "node_modules/@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
+        },
+        "node_modules/@types/mobile-detect": {
+            "version": "1.3.4",
+            "resolved": "https://registry.npmjs.org/@types/mobile-detect/-/mobile-detect-1.3.4.tgz",
+            "integrity": "sha512-MGBTvT5c7aH8eX6szFYP3dWPryNLt5iGlo31XNaJtt8o6jsg6tjn99eEMq9l8T6cPZymsr+J4Jth8+/G/04ZDw==",
+            "dev": true,
+            "dependencies": {
+                "mobile-detect": "*"
+            }
+        },
+        "node_modules/@types/mocha": {
+            "version": "5.2.7",
+            "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
+            "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
+            "dev": true
+        },
+        "node_modules/@types/mongodb": {
+            "version": "3.5.25",
+            "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.5.25.tgz",
+            "integrity": "sha512-2H/Owt+pHCl9YmBOYnXc3VdnxejJEjVdH+QCWL5ZAfPehEn3evygKBX3/vKRv7aTwfNbUd0E5vjJdQklH/9a6w==",
+            "dev": true,
+            "dependencies": {
+                "@types/bson": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/mongoose": {
+            "version": "5.7.28",
+            "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.7.28.tgz",
+            "integrity": "sha512-ll74S2QhC34MSSSk30NHlU8ILESIA2l4mDfAfDse/VM20tT9MRV9WGKWK3HglKRmdL77iMUYMcgHdKJebabtzA==",
+            "dev": true,
+            "dependencies": {
+                "@types/mongodb": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/node": {
+            "version": "10.17.26",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.26.tgz",
+            "integrity": "sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw=="
+        },
+        "node_modules/@types/nodemailer": {
+            "version": "4.6.8",
+            "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.8.tgz",
+            "integrity": "sha512-IX1P3bxDP1VIdZf6/kIWYNmSejkYm9MOyMEtoDFi4DVzKjJ3kY4GhOcOAKs6lZRjqVVmF9UjPOZXuQczlpZThw==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/oauth": {
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz",
+            "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/orderedmap": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/@types/orderedmap/-/orderedmap-1.0.0.tgz",
+            "integrity": "sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==",
+            "dev": true
+        },
+        "node_modules/@types/parse-json": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+            "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
+        },
+        "node_modules/@types/passport": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.3.tgz",
+            "integrity": "sha512-nyztuxtDPQv9utCzU0qW7Gl8BY2Dn8BKlYAFFyxKipFxjaVd96celbkLCV/tRqqBUZ+JB8If3UfgV8347DTo3Q==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*"
+            }
+        },
+        "node_modules/@types/passport-google-oauth20": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.3.tgz",
+            "integrity": "sha512-6EUEGzEg4acwowvgR/yVZIj8S2Kkwc6JmlY2/wnM1wJHNz20o7s1TIGrxnah8ymLgJasYDpy95P3TMMqlmetPw==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/passport": "*",
+                "@types/passport-oauth2": "*"
+            }
+        },
+        "node_modules/@types/passport-local": {
+            "version": "1.0.33",
+            "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
+            "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/passport": "*",
+                "@types/passport-strategy": "*"
+            }
+        },
+        "node_modules/@types/passport-oauth2": {
+            "version": "1.4.9",
+            "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.9.tgz",
+            "integrity": "sha512-QP0q+NVQOaIu2r0e10QWkiUA0Ya5mOBHRJN0UrI+LolMLOP1/VN4EVIpJ3xVwFo+xqNFRoFvFwJhBvKnk7kpUA==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/oauth": "*",
+                "@types/passport": "*"
+            }
+        },
+        "node_modules/@types/passport-strategy": {
+            "version": "0.2.35",
+            "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
+            "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
+            "dev": true,
+            "dependencies": {
+                "@types/express": "*",
+                "@types/passport": "*"
+            }
+        },
+        "node_modules/@types/pdfjs-dist": {
+            "version": "2.1.4",
+            "resolved": "https://registry.npmjs.org/@types/pdfjs-dist/-/pdfjs-dist-2.1.4.tgz",
+            "integrity": "sha512-KnEc8W2IcntVL/SKfRWy2lcJax07xEaO7ghcT0/hc2Lp5UOcmaXAi887RKOLhP8BLKsVGJ7uYH0mYo1uSvbu2A==",
+            "dev": true
+        },
+        "node_modules/@types/prop-types": {
+            "version": "15.7.3",
+            "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+            "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
+        },
+        "node_modules/@types/prosemirror-commands": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-commands/-/prosemirror-commands-1.0.1.tgz",
+            "integrity": "sha512-GeE12m8VT9N1JrzoY//946IX8ZyQOLNmvryJ+BNQs/HvhmXW9EWOcWUE6OBRtxK7Y8SrzSOwx4XmqSgVmK3tGQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-dev-tools": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-dev-tools/-/prosemirror-dev-tools-2.1.0.tgz",
+            "integrity": "sha512-OhnSaC4yrrEMLPRUkEWcHAIPVqgKlLkE4kISqL3cHeAYxASouSPvPMLqhBIbWkGwaozy43DjjVC1OXkxTo+y5Q==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-history": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
+            "integrity": "sha512-BYyPJlWDo3VEnWS5X2DCHXrrAKEjdbCe1DUjGL6R/8hmwMFe3iMJGYdBkOXU1FfkTpw7Z+PlwY/pMyeelVydmg==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-inputrules": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
+            "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-keymap": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.2.tgz",
+            "integrity": "sha512-94aDnpdrdI5S2UM7MQIjauFeo0MI5S7uU+SMT01m5NXT5CZ/NLHhzN0d1V5zKxe7Nh7fVxuZ7l9DTu5nSMN9sw==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-menu": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-menu/-/prosemirror-menu-1.0.2.tgz",
+            "integrity": "sha512-u79CwEQR271k/kjdvRXyPGG7Rn+vPKbJfgSO7vOR/zEYcvSz7lLhBg1OZiSKqfSuhnIAbQh53qLylmB8PTw+WA==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-model": {
+            "version": "1.7.2",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-model/-/prosemirror-model-1.7.2.tgz",
+            "integrity": "sha512-2l+yXvidg3AUHN07mO4Jd8Q84fo6ksFsy7LHUurLYrZ74uTahBp2fzcO49AKZMzww2EulXJ40Kl/OFaQ/7A1fw==",
+            "dev": true,
+            "dependencies": {
+                "@types/orderedmap": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-schema-list": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz",
+            "integrity": "sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA==",
+            "dev": true,
+            "dependencies": {
+                "@types/orderedmap": "*",
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-state": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.2.4.tgz",
+            "integrity": "sha512-Gch4THfZ9QNsRQ7myibU8cG99F3b8/3Gto083ZuutNG72E0VmS8yfQzA5ahbndr5GUIbmKyOD5LqKTBvx/M0qw==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-transform": "*",
+                "@types/prosemirror-view": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-transform": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-transform/-/prosemirror-transform-1.1.1.tgz",
+            "integrity": "sha512-yYCYSoiRH+Wcbl8GJc0PFCzeyMzNQ1vL2xrHHSXZuNcIlH75VoiKrZFeZ6BS9cl8mYXjZrlmdBe8YOxYvyKM6A==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*"
+            }
+        },
+        "node_modules/@types/prosemirror-view": {
+            "version": "1.11.4",
+            "resolved": "https://registry.npmjs.org/@types/prosemirror-view/-/prosemirror-view-1.11.4.tgz",
+            "integrity": "sha512-Hh8v2tpCEMaIesQuw7Y7Pz6imoC1T/bR5OlNGVtp944PZvctXiBvFRkQIb0YvZpt7vVkFzeq2kmR+7mnUfvWiw==",
+            "dev": true,
+            "dependencies": {
+                "@types/prosemirror-model": "*",
+                "@types/prosemirror-state": "*",
+                "@types/prosemirror-transform": "*"
+            }
+        },
+        "node_modules/@types/qs": {
+            "version": "6.9.1",
+            "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz",
+            "integrity": "sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw=="
+        },
+        "node_modules/@types/range-parser": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+            "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA=="
+        },
+        "node_modules/@types/rc-switch": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@types/rc-switch/-/rc-switch-1.9.0.tgz",
+            "integrity": "sha512-L3ZQ2/1GAaiKuQTMO/2sRdhnNNVtnnvdE0ZOL3/+v54j5LguOvYqTSOHPk9nLPi5va3pdRN1MTce3JkJvGZ65A==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react": {
+            "version": "16.9.41",
+            "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.41.tgz",
+            "integrity": "sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug==",
+            "dependencies": {
+                "@types/prop-types": "*",
+                "csstype": "^2.2.0"
+            }
+        },
+        "node_modules/@types/react-autosuggest": {
+            "version": "9.3.14",
+            "resolved": "https://registry.npmjs.org/@types/react-autosuggest/-/react-autosuggest-9.3.14.tgz",
+            "integrity": "sha512-cvGpKaQaNsFbDxTwP56VKVj2FO6SpJ9PsrQtlVzN7aVa/SsMZoQrBLEUx5HQKfIS4Zupb6K4tHmIyTjF7AEcow==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-color": {
+            "version": "2.17.4",
+            "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-2.17.4.tgz",
+            "integrity": "sha512-pAO3+7uHoESg5QMqjnGjw9F7sALjEZsaU41yGiUZbmHiJMoSXH1UklFJ1bZkwhYskaJgiY+AS6wirl17yBh5GA==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*",
+                "@types/reactcss": "*"
+            }
+        },
+        "node_modules/@types/react-datepicker": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-3.0.2.tgz",
+            "integrity": "sha512-xW04NZRF+9ZnzOD3XrlIzBEKgUsN6LVgZJJsXH8NIUlVjyPh+sdtLPfVoDp+GQzGq1M0TuMLNZsv0sJ3N9XwDA==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*",
+                "date-fns": "^2.0.1",
+                "popper.js": "^1.14.1"
+            }
+        },
+        "node_modules/@types/react-dom": {
+            "version": "16.9.8",
+            "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz",
+            "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-grid-layout": {
+            "version": "0.17.1",
+            "resolved": "https://registry.npmjs.org/@types/react-grid-layout/-/react-grid-layout-0.17.1.tgz",
+            "integrity": "sha512-1ssQjX3X2A89jx94jECJ0Ze2EHFRYlBHjRh2pnlwjJj1WaEijXUNvwKnUzKwgNFnyZ91Pzqu9Z3V7Atzi9ge7A==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-measure": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.6.tgz",
+            "integrity": "sha512-FxAwgDVKvxm4SPXu24x9cwzsty8x33UueazHcpxM1UWZlGJI57yIHM2djE3xUJhYVxuzNzi4E8UL3kmCkdh+4A==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-reconciler": {
+            "version": "0.26.1",
+            "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.1.tgz",
+            "integrity": "sha512-jeizEH5o/k6tv42RYNbaulR9KvoSM4RAUq1Q2SXd2HZ7dqgTxN9OIf+GU/sErT7CohB/mUxy9hSjaRLiCPGF5w==",
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-select": {
+            "version": "3.0.13",
+            "resolved": "https://registry.npmjs.org/@types/react-select/-/react-select-3.0.13.tgz",
+            "integrity": "sha512-JxmSArGgzAOtb37+Jz2+3av8rVmp/3s3DGwlcP+g59/a3owkiuuU4/Jajd+qA32beDPHy4gJR2kkxagPY3j9kg==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*",
+                "@types/react-dom": "*",
+                "@types/react-transition-group": "*"
+            }
+        },
+        "node_modules/@types/react-table": {
+            "version": "6.8.7",
+            "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.7.tgz",
+            "integrity": "sha512-1U0xl47jk0BzE+HNHgxZYSLvtybSvnlLhOpW9Mfqf9iuRm/fGqgRab3TKivPCY6Tl7WPFM2hWEJ1GnsuSFc9AQ==",
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/react-transition-group": {
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
+            "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/reactcss": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.3.tgz",
+            "integrity": "sha512-d2gQQ0IL6hXLnoRfVYZukQNWHuVsE75DzFTLPUuyyEhJS8G2VvlE+qfQQ91SJjaMqlURRCNIsX7Jcsw6cEuJlA==",
+            "dev": true,
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/request": {
+            "version": "2.48.5",
+            "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz",
+            "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/caseless": "*",
+                "@types/node": "*",
+                "@types/tough-cookie": "*",
+                "form-data": "^2.5.0"
+            }
+        },
+        "node_modules/@types/request-promise": {
+            "version": "4.1.46",
+            "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.46.tgz",
+            "integrity": "sha512-3Thpj2Va5m0ji3spaCk8YKrjkZyZc6RqUVOphA0n/Xet66AW/AiOAs5vfXhQIL5NmkaO7Jnun7Nl9NEjJ2zBaw==",
+            "dev": true,
+            "dependencies": {
+                "@types/bluebird": "*",
+                "@types/request": "*"
+            }
+        },
+        "node_modules/@types/reveal": {
+            "version": "3.3.33",
+            "resolved": "https://registry.npmjs.org/@types/reveal/-/reveal-3.3.33.tgz",
+            "integrity": "sha512-lKbezA9Oa5LfdSRwFDc/FHEGH4+FjiXh/a/PCSZAmN+KCeQJL/3ClOdAQwOxt3zdHc8XyioT+cNvIOletwRI7A=="
+        },
+        "node_modules/@types/rimraf": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.4.tgz",
+            "integrity": "sha512-8gBudvllD2A/c0CcEX/BivIDorHFt5UI5m46TsNj8DjWCCTTZT74kEe4g+QsY7P/B9WdO98d82zZgXO/RQzu2Q==",
+            "dev": true,
+            "dependencies": {
+                "@types/glob": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/serve-static": {
+            "version": "1.13.3",
+            "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
+            "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
+            "dependencies": {
+                "@types/express-serve-static-core": "*",
+                "@types/mime": "*"
+            }
+        },
+        "node_modules/@types/sharp": {
+            "version": "0.23.1",
+            "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz",
+            "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/shelljs": {
+            "version": "0.8.8",
+            "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.8.tgz",
+            "integrity": "sha512-lD3LWdg6j8r0VRBFahJVaxoW0SIcswxKaFUrmKl33RJVeeoNYQAz4uqCJ5Z6v4oIBOsC5GozX+I5SorIKiTcQA==",
+            "dev": true,
+            "dependencies": {
+                "@types/glob": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@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
+        },
+        "node_modules/@types/socket.io": {
+            "version": "2.1.8",
+            "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.8.tgz",
+            "integrity": "sha512-NIQfh9WwJuJKlgmby4NgwMpoBOmNPCDgaRNPiLYZBtkbHkszK/9R52B5yGkd5a34rbVdAADuo8FhOS/5AZDemw==",
+            "dev": true,
+            "dependencies": {
+                "@types/engine.io": "*",
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/socket.io-client": {
+            "version": "1.4.33",
+            "resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.33.tgz",
+            "integrity": "sha512-m4LnxkljsI9fMsjwpW5QhRpMixo2BeeLpFmg0AE+sS4H1pzAd/cs/ftTiL60FLZgfFa8PFRPx5KsHu8O0bADKQ==",
+            "dev": true
+        },
+        "node_modules/@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
+        },
+        "node_modules/@types/strip-bom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
+            "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
+            "dev": true
+        },
+        "node_modules/@types/strip-json-comments": {
+            "version": "0.0.30",
+            "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
+            "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
+            "dev": true
+        },
+        "node_modules/@types/tapable": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz",
+            "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==",
+            "dev": true
+        },
+        "node_modules/@types/three": {
+            "version": "0.126.2",
+            "resolved": "https://registry.npmjs.org/@types/three/-/three-0.126.2.tgz",
+            "integrity": "sha512-6JqTgijtfXcTJik8NtiNxr2L90ex6ElM00qilOGeUcrEsJLOdzLJSIkXHUYS+KPAYQYtRJQKD6XaXds3HjS+gg=="
+        },
+        "node_modules/@types/tough-cookie": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
+            "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
+            "dev": true
+        },
+        "node_modules/@types/typescript": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz",
+            "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=",
+            "dev": true,
+            "dependencies": {
+                "typescript": "*"
+            }
+        },
+        "node_modules/@types/uglify-js": {
+            "version": "3.13.0",
+            "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz",
+            "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==",
+            "dev": true,
+            "dependencies": {
+                "source-map": "^0.6.1"
+            }
+        },
+        "node_modules/@types/uglify-js/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/@types/uuid": {
+            "version": "3.4.9",
+            "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.9.tgz",
+            "integrity": "sha512-XDwyIlt/47l2kWLTzw/mtrpLdB+GPSskR2n/PIcPn+VYhVO77rGhRncIR5GPU0KRzXuqkDO+J5qqrG0Y8P6jzQ==",
+            "dev": true
+        },
+        "node_modules/@types/valid-url": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/@types/valid-url/-/valid-url-1.0.3.tgz",
+            "integrity": "sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ==",
+            "dev": true
+        },
+        "node_modules/@types/webpack": {
+            "version": "4.41.27",
+            "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.27.tgz",
+            "integrity": "sha512-wK/oi5gcHi72VMTbOaQ70VcDxSQ1uX8S2tukBK9ARuGXrYM/+u4ou73roc7trXDNmCxCoerE8zruQqX/wuHszA==",
+            "dev": true,
+            "dependencies": {
+                "@types/anymatch": "*",
+                "@types/node": "*",
+                "@types/tapable": "^1",
+                "@types/uglify-js": "*",
+                "@types/webpack-sources": "*",
+                "source-map": "^0.6.0"
+            }
+        },
+        "node_modules/@types/webpack-dev-middleware": {
+            "version": "2.0.7",
+            "resolved": "https://registry.npmjs.org/@types/webpack-dev-middleware/-/webpack-dev-middleware-2.0.7.tgz",
+            "integrity": "sha512-pArv7YnqpbSCOBWiRlR1KgqVorlzkIiwto66hI8Gdgp5ATQAC+Ug4QVz69ZI1dP+D5Rs8QWnbT81tE4tcMuTag==",
+            "dev": true,
+            "dependencies": {
+                "@types/connect": "*",
+                "@types/memory-fs": "*",
+                "@types/webpack": "^4",
+                "loglevel": "^1.6.2"
+            }
+        },
+        "node_modules/@types/webpack-hot-middleware": {
+            "version": "2.25.4",
+            "resolved": "https://registry.npmjs.org/@types/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz",
+            "integrity": "sha512-6tQb9EBKIANZYUVLQYWiWfDFVe7FhXSj4bB2EF5QB7VtYWL3HDR+y/zqjZPAnCorv0spLqVMRqjRK8AmhfocMw==",
+            "dev": true,
+            "dependencies": {
+                "@types/connect": "*",
+                "@types/webpack": "^4"
+            }
+        },
+        "node_modules/@types/webpack-sources": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz",
+            "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==",
+            "dev": true,
+            "dependencies": {
+                "@types/node": "*",
+                "@types/source-list-map": "*",
+                "source-map": "^0.7.3"
+            }
+        },
+        "node_modules/@types/webpack-sources/node_modules/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,
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@types/webpack/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/@types/webscopeio__react-textarea-autocomplete": {
+            "version": "4.6.1",
+            "resolved": "https://registry.npmjs.org/@types/webscopeio__react-textarea-autocomplete/-/webscopeio__react-textarea-autocomplete-4.6.1.tgz",
+            "integrity": "sha512-rdiDMsTbyFJRbC2BYKIgiAFG/SFkaDGYQYfzo3U2T+EjMCE0JZ8IHZ9nZrJ2Tm83Blrj66cnaEc0H3iwwRqQMA==",
+            "dependencies": {
+                "@types/react": "*"
+            }
+        },
+        "node_modules/@types/xregexp": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/@types/xregexp/-/xregexp-4.3.0.tgz",
+            "integrity": "sha512-3gJTS9gt27pS7U9q5IVqo4YvKSlkf2ck8ish6etuDj6LIRxkL/2Y8RMUtK/QzvE1Yv2zwWV5yemI2BS0GGGFnA==",
+            "dev": true
+        },
+        "node_modules/@types/yauzl": {
+            "version": "2.9.1",
+            "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
+            "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+            "optional": true,
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/@types/youtube": {
+            "version": "0.0.39",
+            "resolved": "https://registry.npmjs.org/@types/youtube/-/youtube-0.0.39.tgz",
+            "integrity": "sha512-naVjyTZT/CoNwEQW3+mf9E/x6sgB7QIPbRDtVlPUpHlmuQTk+j6gQBy0T5CRkV8oC0GYQjMgfr3VdueTSVLTjw==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/ast": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+            "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/helper-module-context": "1.9.0",
+                "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+                "@webassemblyjs/wast-parser": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/floating-point-hex-parser": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+            "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/helper-api-error": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+            "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/helper-buffer": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+            "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/helper-code-frame": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+            "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/wast-printer": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/helper-fsm": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+            "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/helper-module-context": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+            "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/helper-wasm-bytecode": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+            "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/helper-wasm-section": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+            "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-buffer": "1.9.0",
+                "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+                "@webassemblyjs/wasm-gen": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/ieee754": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+            "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+            "dev": true,
+            "dependencies": {
+                "@xtuc/ieee754": "^1.2.0"
+            }
+        },
+        "node_modules/@webassemblyjs/leb128": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+            "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+            "dev": true,
+            "dependencies": {
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webassemblyjs/utf8": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+            "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+            "dev": true
+        },
+        "node_modules/@webassemblyjs/wasm-edit": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+            "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-buffer": "1.9.0",
+                "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+                "@webassemblyjs/helper-wasm-section": "1.9.0",
+                "@webassemblyjs/wasm-gen": "1.9.0",
+                "@webassemblyjs/wasm-opt": "1.9.0",
+                "@webassemblyjs/wasm-parser": "1.9.0",
+                "@webassemblyjs/wast-printer": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-gen": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+            "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+                "@webassemblyjs/ieee754": "1.9.0",
+                "@webassemblyjs/leb128": "1.9.0",
+                "@webassemblyjs/utf8": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-opt": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+            "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-buffer": "1.9.0",
+                "@webassemblyjs/wasm-gen": "1.9.0",
+                "@webassemblyjs/wasm-parser": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/wasm-parser": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+            "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-api-error": "1.9.0",
+                "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+                "@webassemblyjs/ieee754": "1.9.0",
+                "@webassemblyjs/leb128": "1.9.0",
+                "@webassemblyjs/utf8": "1.9.0"
+            }
+        },
+        "node_modules/@webassemblyjs/wast-parser": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+            "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+                "@webassemblyjs/helper-api-error": "1.9.0",
+                "@webassemblyjs/helper-code-frame": "1.9.0",
+                "@webassemblyjs/helper-fsm": "1.9.0",
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webassemblyjs/wast-printer": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+            "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/wast-parser": "1.9.0",
+                "@xtuc/long": "4.2.2"
+            }
+        },
+        "node_modules/@webscopeio/react-textarea-autocomplete": {
+            "version": "4.7.0",
+            "resolved": "https://registry.npmjs.org/@webscopeio/react-textarea-autocomplete/-/react-textarea-autocomplete-4.7.0.tgz",
+            "integrity": "sha512-uzH7PUlXQk6jCTh1eGZdXjvjxveZpznhQywX5I5ojsXgre+XSzlK66chdDdfi+lQABC3N3TzfSq6Hlxa8hlrLA==",
+            "dependencies": {
+                "custom-event": "^1.0.1",
+                "textarea-caret": "3.0.2"
+            }
+        },
+        "node_modules/@webscopeio/react-textarea-autocomplete/node_modules/textarea-caret": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.0.2.tgz",
+            "integrity": "sha1-82DEhpmqGr9xhoCkOjGoUGZcLK8="
+        },
+        "node_modules/@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
+        },
+        "node_modules/@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
+        },
+        "node_modules/abab": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
+            "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==",
+            "dev": true
+        },
+        "node_modules/abbrev": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+            "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+        },
+        "node_modules/abort-controller": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+            "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+            "dependencies": {
+                "event-target-shim": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=6.5"
+            }
+        },
+        "node_modules/accepts": {
+            "version": "1.3.7",
+            "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+            "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+            "dependencies": {
+                "mime-types": "~2.1.24",
+                "negotiator": "0.6.2"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/acorn": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+            "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/acorn-globals": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
+            "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
+            "dependencies": {
+                "acorn": "^4.0.4"
+            }
+        },
+        "node_modules/acorn-globals/node_modules/acorn": {
+            "version": "4.0.13",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+            "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/acorn-jsx": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
+            "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ=="
+        },
+        "node_modules/acorn-walk": {
+            "version": "6.2.0",
+            "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+            "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/adm-zip": {
+            "version": "0.4.16",
+            "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
+            "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==",
+            "engines": {
+                "node": ">=0.3.0"
+            }
+        },
+        "node_modules/after": {
+            "version": "0.8.2",
+            "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+            "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
+        },
+        "node_modules/agent-base": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
+            "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
+            "dependencies": {
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/agent-base/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/ajv": {
+            "version": "6.12.2",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
+            "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/ajv-keywords": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz",
+            "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ=="
+        },
+        "node_modules/align-text": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+            "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+            "dependencies": {
+                "kind-of": "^3.0.2",
+                "longest": "^1.0.1",
+                "repeat-string": "^1.5.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/align-text/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/align-text/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/amdefine": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+            "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+            "engines": {
+                "node": ">=0.4.2"
+            }
+        },
+        "node_modules/ansi-align": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+            "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+            "dependencies": {
+                "string-width": "^2.0.0"
+            }
+        },
+        "node_modules/ansi-colors": {
+            "version": "3.2.3",
+            "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+            "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/ansi-escape-sequences": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
+            "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
+            "dependencies": {
+                "array-back": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/ansi-escape-sequences/node_modules/array-back": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+            "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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,
+            "engines": [
+                "node >= 0.8.0"
+            ],
+            "bin": {
+                "ansi-html": "bin/ansi-html"
+            }
+        },
+        "node_modules/ansi-regex": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+            "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "color-convert": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/any-promise": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+            "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+        },
+        "node_modules/anymatch": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+            "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+            "dependencies": {
+                "micromatch": "^3.1.4",
+                "normalize-path": "^2.1.1"
+            }
+        },
+        "node_modules/anymatch/node_modules/normalize-path": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+            "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+            "dependencies": {
+                "remove-trailing-separator": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/aproba": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+            "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+        },
+        "node_modules/archiver": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz",
+            "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==",
+            "dependencies": {
+                "archiver-utils": "^2.1.0",
+                "async": "^2.6.3",
+                "buffer-crc32": "^0.2.1",
+                "glob": "^7.1.4",
+                "readable-stream": "^3.4.0",
+                "tar-stream": "^2.1.0",
+                "zip-stream": "^2.1.2"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/archiver-utils": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
+            "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
+            "dependencies": {
+                "glob": "^7.1.4",
+                "graceful-fs": "^4.2.0",
+                "lazystream": "^1.0.0",
+                "lodash.defaults": "^4.2.0",
+                "lodash.difference": "^4.5.0",
+                "lodash.flatten": "^4.4.0",
+                "lodash.isplainobject": "^4.0.6",
+                "lodash.union": "^4.6.0",
+                "normalize-path": "^3.0.0",
+                "readable-stream": "^2.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/archiver-utils/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/are-we-there-yet": {
+            "version": "1.1.5",
+            "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+            "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+            "dependencies": {
+                "delegates": "^1.0.0",
+                "readable-stream": "^2.0.6"
+            }
+        },
+        "node_modules/are-we-there-yet/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/arg": {
+            "version": "4.1.3",
+            "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+            "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+            "dev": true
+        },
+        "node_modules/argparse": {
+            "version": "1.0.10",
+            "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+            "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+            "dependencies": {
+                "sprintf-js": "~1.0.2"
+            }
+        },
+        "node_modules/arr-diff": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+            "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/arr-union": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+            "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/array-back": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+            "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+            "dependencies": {
+                "typical": "^2.6.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/array-batcher": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/array-batcher/-/array-batcher-1.2.3.tgz",
+            "integrity": "sha512-/IOrwn4ZJi7YqTZrs3k+wQN5nKhjtTqL5ZKkzB+sKJlPeJzpMnRc3o8T9yt8/ZJiSldd+PwTHjM+//UsaszOOw==",
+            "dependencies": {
+                "@types/node": "^12.7.5",
+                "chai": "^4.2.0",
+                "mocha": "^6.2.0",
+                "request": "^2.88.0",
+                "request-promise": "^4.2.4"
+            }
+        },
+        "node_modules/array-batcher/node_modules/@types/node": {
+            "version": "12.12.37",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.37.tgz",
+            "integrity": "sha512-4mXKoDptrXAwZErQHrLzpe0FN/0Wmf5JRniSVIdwUrtDf9wnmEV1teCNLBo/TwuXhkK/bVegoEn/wmb+x0AuPg=="
+        },
+        "node_modules/array-batcher/node_modules/glob": {
+            "version": "7.1.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+            "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/array-batcher/node_modules/mocha": {
+            "version": "6.2.3",
+            "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz",
+            "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==",
+            "dependencies": {
+                "ansi-colors": "3.2.3",
+                "browser-stdout": "1.3.1",
+                "debug": "3.2.6",
+                "diff": "3.5.0",
+                "escape-string-regexp": "1.0.5",
+                "find-up": "3.0.0",
+                "glob": "7.1.3",
+                "growl": "1.10.5",
+                "he": "1.2.0",
+                "js-yaml": "3.13.1",
+                "log-symbols": "2.2.0",
+                "minimatch": "3.0.4",
+                "mkdirp": "0.5.4",
+                "ms": "2.1.1",
+                "node-environment-flags": "1.0.5",
+                "object.assign": "4.1.0",
+                "strip-json-comments": "2.0.1",
+                "supports-color": "6.0.0",
+                "which": "1.3.1",
+                "wide-align": "1.1.3",
+                "yargs": "13.3.2",
+                "yargs-parser": "13.1.2",
+                "yargs-unparser": "1.6.0"
+            },
+            "bin": {
+                "_mocha": "bin/_mocha",
+                "mocha": "bin/mocha"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/array-batcher/node_modules/supports-color": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+            "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/array-equal": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+            "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+            "dev": true
+        },
+        "node_modules/array-find-index": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+            "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/array-flatten": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+            "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+        },
+        "node_modules/array-union": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+            "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+            "dev": true,
+            "dependencies": {
+                "array-uniq": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/array-unique": {
+            "version": "0.3.2",
+            "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+            "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/arrify": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+            "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/asap": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+            "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+        },
+        "node_modules/asn1": {
+            "version": "0.2.4",
+            "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+            "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+            "dependencies": {
+                "safer-buffer": "~2.1.0"
+            }
+        },
+        "node_modules/asn1.js": {
+            "version": "5.4.1",
+            "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+            "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+            "dev": true,
+            "dependencies": {
+                "bn.js": "^4.0.0",
+                "inherits": "^2.0.1",
+                "minimalistic-assert": "^1.0.0",
+                "safer-buffer": "^2.1.0"
+            }
+        },
+        "node_modules/asn1.js/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/assert": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+            "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+            "dev": true,
+            "dependencies": {
+                "object-assign": "^4.1.1",
+                "util": "0.10.3"
+            }
+        },
+        "node_modules/assert-plus": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+            "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/assert/node_modules/inherits": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+            "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+            "dev": true
+        },
+        "node_modules/assert/node_modules/util": {
+            "version": "0.10.3",
+            "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+            "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+            "dev": true,
+            "dependencies": {
+                "inherits": "2.0.1"
+            }
+        },
+        "node_modules/assertion-error": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+            "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/assign-symbols": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+            "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/async": {
+            "version": "2.6.3",
+            "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+            "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+            "dependencies": {
+                "lodash": "^4.17.14"
+            }
+        },
+        "node_modules/async-each": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+            "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ=="
+        },
+        "node_modules/async-foreach": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+            "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/asynckit": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+            "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+        },
+        "node_modules/atob": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+            "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+            "bin": {
+                "atob": "bin/atob.js"
+            },
+            "engines": {
+                "node": ">= 4.5.0"
+            }
+        },
+        "node_modules/awesome-typescript-loader": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz",
+            "integrity": "sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==",
+            "dev": true,
+            "dependencies": {
+                "chalk": "^2.4.1",
+                "enhanced-resolve": "^4.0.0",
+                "loader-utils": "^1.1.0",
+                "lodash": "^4.17.5",
+                "micromatch": "^3.1.9",
+                "mkdirp": "^0.5.1",
+                "source-map-support": "^0.5.3",
+                "webpack-log": "^1.2.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/aws4": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
+            "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
+        },
+        "node_modules/axios": {
+            "version": "0.19.2",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+            "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+            "dependencies": {
+                "follow-redirects": "1.5.10"
+            }
+        },
+        "node_modules/axios/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/axios/node_modules/follow-redirects": {
+            "version": "1.5.10",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+            "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+            "dependencies": {
+                "debug": "=3.1.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/axios/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "chalk": "^1.1.3",
+                "esutils": "^2.0.2",
+                "js-tokens": "^3.0.2"
+            }
+        },
+        "node_modules/babel-code-frame/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/babel-code-frame/node_modules/ansi-styles": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+            "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/babel-code-frame/node_modules/chalk": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+            "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/babel-code-frame/node_modules/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
+        },
+        "node_modules/babel-code-frame/node_modules/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,
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/babel-code-frame/node_modules/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,
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/babel-plugin-emotion": {
+            "version": "10.0.33",
+            "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz",
+            "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==",
+            "dependencies": {
+                "@babel/helper-module-imports": "^7.0.0",
+                "@emotion/hash": "0.8.0",
+                "@emotion/memoize": "0.7.4",
+                "@emotion/serialize": "^0.11.16",
+                "babel-plugin-macros": "^2.0.0",
+                "babel-plugin-syntax-jsx": "^6.18.0",
+                "convert-source-map": "^1.5.0",
+                "escape-string-regexp": "^1.0.5",
+                "find-root": "^1.1.0",
+                "source-map": "^0.5.7"
+            }
+        },
+        "node_modules/babel-plugin-macros": {
+            "version": "2.8.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
+            "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
+            "dependencies": {
+                "@babel/runtime": "^7.7.2",
+                "cosmiconfig": "^6.0.0",
+                "resolve": "^1.12.0"
+            }
+        },
+        "node_modules/babel-plugin-styled-components": {
+            "version": "1.10.7",
+            "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz",
+            "integrity": "sha512-MBMHGcIA22996n9hZRf/UJLVVgkEOITuR2SvjHLb5dSTUyR4ZRGn+ngITapes36FI3WLxZHfRhkA1ffHxihOrg==",
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": "^7.0.0",
+                "@babel/helper-module-imports": "^7.0.0",
+                "babel-plugin-syntax-jsx": "^6.18.0",
+                "lodash": "^4.17.11"
+            }
+        },
+        "node_modules/babel-plugin-syntax-jsx": {
+            "version": "6.18.0",
+            "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+            "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "core-js": "^2.4.0",
+                "regenerator-runtime": "^0.11.0"
+            }
+        },
+        "node_modules/babel-runtime/node_modules/core-js": {
+            "version": "2.6.11",
+            "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz",
+            "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==",
+            "hasInstallScript": true
+        },
+        "node_modules/babel-runtime/node_modules/regenerator-runtime": {
+            "version": "0.11.1",
+            "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+            "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+        },
+        "node_modules/babel-types": {
+            "version": "6.26.0",
+            "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+            "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+            "dependencies": {
+                "babel-runtime": "^6.26.0",
+                "esutils": "^2.0.2",
+                "lodash": "^4.17.4",
+                "to-fast-properties": "^1.0.3"
+            }
+        },
+        "node_modules/babel-types/node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/babylon": {
+            "version": "6.18.0",
+            "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+            "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+            "bin": {
+                "babylon": "bin/babylon.js"
+            }
+        },
+        "node_modules/backo2": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+            "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
+        },
+        "node_modules/balanced-match": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+            "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+        },
+        "node_modules/base": {
+            "version": "0.11.2",
+            "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+            "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/base/node_modules/define-property": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+            "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+            "dependencies": {
+                "is-descriptor": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/base/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/base/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/base/node_modules/is-descriptor": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+            "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+            "dependencies": {
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/base16": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
+            "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
+        },
+        "node_modules/base64-arraybuffer": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+            "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+            "engines": {
+                "node": ">= 0.6.0"
+            }
+        },
+        "node_modules/base64-js": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
+            "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
+        },
+        "node_modules/base64id": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
+            "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==",
+            "engines": {
+                "node": "^4.5.0 || >= 5.9"
+            }
+        },
+        "node_modules/base64url": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
+            "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/batch": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+            "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+            "dev": true
+        },
+        "node_modules/bcrypt-nodejs": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz",
+            "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs="
+        },
+        "node_modules/bcrypt-pbkdf": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+            "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+            "dependencies": {
+                "tweetnacl": "^0.14.3"
+            }
+        },
+        "node_modules/better-assert": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+            "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+            "dependencies": {
+                "callsite": "1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/bezier-curve": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/bezier-curve/-/bezier-curve-1.0.0.tgz",
+            "integrity": "sha1-o9+v6rEqlMRicw1QeYxSqEBdc3k="
+        },
+        "node_modules/big.js": {
+            "version": "5.2.2",
+            "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+            "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/bignumber.js": {
+            "version": "7.2.1",
+            "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
+            "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/binary-extensions": {
+            "version": "1.13.1",
+            "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+            "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/bindings": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz",
+            "integrity": "sha512-i47mqjF9UbjxJhxGf+pZ6kSxrnI3wBLlnGI2ArWJ4r0VrvDS7ZYXkprq/pLaBWYq4GM0r4zdHY+NNRqEMU7uew=="
+        },
+        "node_modules/bl": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz",
+            "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==",
+            "dependencies": {
+                "buffer": "^5.5.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.4.0"
+            }
+        },
+        "node_modules/blob": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+            "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
+        },
+        "node_modules/block-stream": {
+            "version": "0.0.9",
+            "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+            "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+            "dependencies": {
+                "inherits": "~2.0.0"
+            },
+            "engines": {
+                "node": "0.4 || >=0.5.8"
+            }
+        },
+        "node_modules/bluebird": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+            "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+        },
+        "node_modules/blueimp-load-image": {
+            "version": "2.31.0",
+            "resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.31.0.tgz",
+            "integrity": "sha512-6sTGh1OiUmuH8ftAYvUzALivoOmcnahinGmjZFI4puZVowXoKTn/bXtth7N1skW5AlezEOfjgFH4lNXHeNRQog=="
+        },
+        "node_modules/bn.js": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz",
+            "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==",
+            "dev": true
+        },
+        "node_modules/body-parser": {
+            "version": "1.19.0",
+            "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+            "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/body-parser/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/body-parser/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/body-parser/node_modules/qs": {
+            "version": "6.7.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+            "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/bonjour": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+            "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/bonjour/node_modules/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
+        },
+        "node_modules/boolbase": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+            "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+        },
+        "node_modules/bootstrap": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz",
+            "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA=="
+        },
+        "node_modules/bowser": {
+            "version": "1.9.4",
+            "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.4.tgz",
+            "integrity": "sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ=="
+        },
+        "node_modules/boxen": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+            "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
+            "dependencies": {
+                "ansi-align": "^2.0.0",
+                "camelcase": "^4.0.0",
+                "chalk": "^2.0.1",
+                "cli-boxes": "^1.0.0",
+                "string-width": "^2.0.0",
+                "term-size": "^1.2.0",
+                "widest-line": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/boxen/node_modules/camelcase": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+            "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/braces": {
+            "version": "2.3.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+            "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/braces/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/braces/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/brorand": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+            "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+            "dev": true
+        },
+        "node_modules/browser-process-hrtime": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+            "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+            "dev": true
+        },
+        "node_modules/browser-stdout": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+            "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "browserify-aes": "^1.0.4",
+                "browserify-des": "^1.0.0",
+                "evp_bytestokey": "^1.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "cipher-base": "^1.0.1",
+                "des.js": "^1.0.0",
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.1.2"
+            }
+        },
+        "node_modules/browserify-rsa": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+            "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+            "dev": true,
+            "dependencies": {
+                "bn.js": "^5.0.0",
+                "randombytes": "^2.0.1"
+            }
+        },
+        "node_modules/browserify-sign": {
+            "version": "4.2.1",
+            "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+            "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+            "dev": true,
+            "dependencies": {
+                "bn.js": "^5.1.1",
+                "browserify-rsa": "^4.0.1",
+                "create-hash": "^1.2.0",
+                "create-hmac": "^1.1.7",
+                "elliptic": "^6.5.3",
+                "inherits": "^2.0.4",
+                "parse-asn1": "^5.1.5",
+                "readable-stream": "^3.6.0",
+                "safe-buffer": "^5.2.0"
+            }
+        },
+        "node_modules/browserify-sign/node_modules/safe-buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+            "dev": true
+        },
+        "node_modules/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,
+            "dependencies": {
+                "pako": "~1.0.5"
+            }
+        },
+        "node_modules/bson": {
+            "version": "1.0.9",
+            "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz",
+            "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==",
+            "engines": {
+                "node": ">=0.6.19"
+            }
+        },
+        "node_modules/buffer": {
+            "version": "5.6.0",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz",
+            "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==",
+            "dependencies": {
+                "base64-js": "^1.0.2",
+                "ieee754": "^1.1.4"
+            }
+        },
+        "node_modules/buffer-crc32": {
+            "version": "0.2.13",
+            "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+            "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/buffer-equal-constant-time": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+            "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
+        },
+        "node_modules/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=="
+        },
+        "node_modules/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
+        },
+        "node_modules/buffer-shims": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+            "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
+        },
+        "node_modules/buffer-xor": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+            "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+            "dev": true
+        },
+        "node_modules/built-in-math-eval": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/built-in-math-eval/-/built-in-math-eval-0.3.0.tgz",
+            "integrity": "sha1-JA3CHLOJQ5WIxhxGDrAHZJfvxBw=",
+            "dependencies": {
+                "math-codegen": "^0.3.5"
+            }
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/bytes": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+            "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/cacache": {
+            "version": "10.0.4",
+            "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
+            "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
+            "dev": true,
+            "dependencies": {
+                "bluebird": "^3.5.1",
+                "chownr": "^1.0.1",
+                "glob": "^7.1.2",
+                "graceful-fs": "^4.1.11",
+                "lru-cache": "^4.1.1",
+                "mississippi": "^2.0.0",
+                "mkdirp": "^0.5.1",
+                "move-concurrently": "^1.0.1",
+                "promise-inflight": "^1.0.1",
+                "rimraf": "^2.6.2",
+                "ssri": "^5.2.4",
+                "unique-filename": "^1.1.0",
+                "y18n": "^4.0.0"
+            }
+        },
+        "node_modules/cacache/node_modules/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,
+            "dependencies": {
+                "pseudomap": "^1.0.2",
+                "yallist": "^2.1.2"
+            }
+        },
+        "node_modules/cacache/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/cacache/node_modules/yallist": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+            "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+            "dev": true
+        },
+        "node_modules/cache-base": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+            "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/caller-callsite": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+            "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+            "dependencies": {
+                "callsites": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/caller-callsite/node_modules/callsites": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+            "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/caller-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+            "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+            "dependencies": {
+                "caller-callsite": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/callsite": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+            "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/callsites": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+            "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/camelcase": {
+            "version": "5.3.1",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+            "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/camelcase-keys": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+            "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+            "dependencies": {
+                "camelcase": "^2.0.0",
+                "map-obj": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/camelcase-keys/node_modules/camelcase": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+            "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/camelize": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+            "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+        },
+        "node_modules/canvas": {
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.6.1.tgz",
+            "integrity": "sha512-S98rKsPcuhfTcYbtF53UIJhcbgIAK533d1kJKMwsMwAIFgfd58MOyxRud3kktlzWiEkFliaJtvyZCBtud/XVEA==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "nan": "^2.14.0",
+                "node-pre-gyp": "^0.11.0",
+                "simple-get": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/canvas/node_modules/node-pre-gyp": {
+            "version": "0.11.0",
+            "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
+            "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
+            "dependencies": {
+                "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"
+            },
+            "bin": {
+                "node-pre-gyp": "bin/node-pre-gyp"
+            }
+        },
+        "node_modules/canvas/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/capture-stack-trace": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
+            "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/caseless": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+            "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+        },
+        "node_modules/center-align": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+            "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+            "dependencies": {
+                "align-text": "^0.1.3",
+                "lazy-cache": "^1.0.3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chai": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+            "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+            "dependencies": {
+                "assertion-error": "^1.1.0",
+                "check-error": "^1.0.2",
+                "deep-eql": "^3.0.1",
+                "get-func-name": "^2.0.0",
+                "pathval": "^1.1.0",
+                "type-detect": "^4.0.5"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/chain-function": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz",
+            "integrity": "sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg=="
+        },
+        "node_modules/chalk": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+            "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+            "dependencies": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/change-emitter": {
+            "version": "0.1.6",
+            "resolved": "https://registry.npmjs.org/change-emitter/-/change-emitter-0.1.6.tgz",
+            "integrity": "sha1-6LL+PX8at9aaMhma/5HqaTFAlRU="
+        },
+        "node_modules/character-parser": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
+            "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
+            "dependencies": {
+                "is-regex": "^1.0.3"
+            }
+        },
+        "node_modules/check-error": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+            "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/cheerio": {
+            "version": "1.0.0-rc.3",
+            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
+            "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
+            "dependencies": {
+                "css-select": "~1.2.0",
+                "dom-serializer": "~0.1.1",
+                "entities": "~1.1.1",
+                "htmlparser2": "^3.9.1",
+                "lodash": "^4.15.0",
+                "parse5": "^3.0.1"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/cheerio/node_modules/dom-serializer": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+            "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+            "dependencies": {
+                "domelementtype": "^1.3.0",
+                "entities": "^1.1.1"
+            }
+        },
+        "node_modules/child_process": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
+            "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o="
+        },
+        "node_modules/chokidar": {
+            "version": "2.1.8",
+            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+            "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+            "dependencies": {
+                "anymatch": "^2.0.0",
+                "async-each": "^1.0.1",
+                "braces": "^2.3.2",
+                "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"
+            },
+            "optionalDependencies": {
+                "fsevents": "^1.2.7"
+            }
+        },
+        "node_modules/chokidar/node_modules/bindings": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+            "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+            "optional": true,
+            "dependencies": {
+                "file-uri-to-path": "1.0.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents": {
+            "version": "1.2.12",
+            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz",
+            "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==",
+            "bundleDependencies": [
+                "node-pre-gyp"
+            ],
+            "hasInstallScript": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "dependencies": {
+                "bindings": "^1.5.0",
+                "nan": "^2.12.1",
+                "node-pre-gyp": "*"
+            },
+            "engines": {
+                "node": ">= 4.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/abbrev": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/are-we-there-yet": {
+            "version": "1.1.5",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "delegates": "^1.0.0",
+                "readable-stream": "^2.0.6"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/balanced-match": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/chownr": {
+            "version": "1.1.4",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/code-point-at": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/concat-map": {
+            "version": "0.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/console-control-strings": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/core-util-is": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/debug": {
+            "version": "3.2.6",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/deep-extend": {
+            "version": "0.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/delegates": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/detect-libc": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "optional": true,
+            "bin": {
+                "detect-libc": "bin/detect-libc.js"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/fs-minipass": {
+            "version": "1.2.7",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^2.6.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/gauge": {
+            "version": "2.7.4",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/glob": {
+            "version": "7.1.6",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/has-unicode": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/iconv-lite": {
+            "version": "0.4.24",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/ignore-walk": {
+            "version": "3.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "minimatch": "^3.0.4"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/inflight": {
+            "version": "1.0.6",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/inherits": {
+            "version": "2.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/ini": {
+            "version": "1.3.5",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/is-fullwidth-code-point": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "number-is-nan": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/isarray": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/minimatch": {
+            "version": "3.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/minimist": {
+            "version": "1.2.5",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/minipass": {
+            "version": "2.9.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/minizlib": {
+            "version": "1.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "minipass": "^2.9.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/mkdirp": {
+            "version": "0.5.3",
+            "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "minimist": "^1.2.5"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/ms": {
+            "version": "2.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/needle": {
+            "version": "2.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "debug": "^3.2.6",
+                "iconv-lite": "^0.4.4",
+                "sax": "^1.2.4"
+            },
+            "bin": {
+                "needle": "bin/needle"
+            },
+            "engines": {
+                "node": ">= 4.4.x"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/node-pre-gyp": {
+            "version": "0.14.0",
+            "inBundle": true,
+            "license": "BSD-3-Clause",
+            "optional": true,
+            "dependencies": {
+                "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.4.2"
+            },
+            "bin": {
+                "node-pre-gyp": "bin/node-pre-gyp"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/nopt": {
+            "version": "4.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "abbrev": "1",
+                "osenv": "^0.1.4"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/npm-bundled": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/npm-normalize-package-bin": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/npm-packlist": {
+            "version": "1.4.8",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "ignore-walk": "^3.0.1",
+                "npm-bundled": "^1.0.1",
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/npmlog": {
+            "version": "4.1.2",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "are-we-there-yet": "~1.1.2",
+                "console-control-strings": "~1.1.0",
+                "gauge": "~2.7.3",
+                "set-blocking": "~2.0.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/number-is-nan": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/object-assign": {
+            "version": "4.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/once": {
+            "version": "1.4.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/os-homedir": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/os-tmpdir": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/osenv": {
+            "version": "0.1.5",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "os-homedir": "^1.0.0",
+                "os-tmpdir": "^1.0.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/path-is-absolute": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/process-nextick-args": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/rc": {
+            "version": "1.2.8",
+            "inBundle": true,
+            "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+            "optional": true,
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/rimraf": {
+            "version": "2.7.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/sax": {
+            "version": "1.2.4",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/semver": {
+            "version": "5.7.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/set-blocking": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/signal-exit": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/string-width": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/strip-ansi": {
+            "version": "3.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/tar": {
+            "version": "4.4.13",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "fs-minipass": "^1.2.5",
+                "minipass": "^2.8.6",
+                "minizlib": "^1.2.1",
+                "mkdirp": "^0.5.0",
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=4.5"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/wide-align": {
+            "version": "1.1.3",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true,
+            "dependencies": {
+                "string-width": "^1.0.2 || 2"
+            }
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/wrappy": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chokidar/node_modules/fsevents/node_modules/yallist": {
+            "version": "3.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "optional": true
+        },
+        "node_modules/chownr": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+        },
+        "node_modules/chrome": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/chrome/-/chrome-0.1.0.tgz",
+            "integrity": "sha1-9h2beS/v6MGUxwVt3BAscmqGQyk=",
+            "dependencies": {
+                "exeq": "^2.2.0",
+                "plist": "^1.1.0"
+            },
+            "bin": {
+                "chrome": "index.js"
+            }
+        },
+        "node_modules/chrome-trace-event": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
+            "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==",
+            "dev": true,
+            "engines": {
+                "node": ">=6.0"
+            }
+        },
+        "node_modules/ci-info": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
+            "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/clamp": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz",
+            "integrity": "sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ="
+        },
+        "node_modules/class-transformer": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.2.3.tgz",
+            "integrity": "sha512-qsP+0xoavpOlJHuYsQJsN58HXSl8Jvveo+T37rEvCEeRfMWoytAyR0Ua/YsFgpM6AZYZ/og2PJwArwzJl1aXtQ=="
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "arr-union": "^3.1.0",
+                "define-property": "^0.2.5",
+                "isobject": "^3.0.0",
+                "static-extend": "^0.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/class-utils/node_modules/define-property": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+            "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+            "dependencies": {
+                "is-descriptor": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/classnames": {
+            "version": "2.2.6",
+            "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
+            "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
+        },
+        "node_modules/clean-css": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
+            "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
+            "dependencies": {
+                "source-map": "~0.6.0"
+            },
+            "engines": {
+                "node": ">= 4.0"
+            }
+        },
+        "node_modules/clean-css/node_modules/source-map": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+            "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/cli-boxes": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+            "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/cliss": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/cliss/-/cliss-0.0.2.tgz",
+            "integrity": "sha512-6rj9pgdukjT994Md13JCUAgTk91abAKrygL9sAvmHY4F6AKMOV8ccGaxhUUfcBuyg3sundWnn3JE0Mc9W6ZYqw==",
+            "dependencies": {
+                "command-line-usage": "^4.0.1",
+                "deepmerge": "^2.0.0",
+                "get-stdin": "^5.0.1",
+                "inspect-parameters-declaration": "0.0.9",
+                "object-to-arguments": "0.0.8",
+                "pipe-functions": "^1.3.0",
+                "strip-ansi": "^4.0.0",
+                "yargs-parser": "^7.0.0"
+            }
+        },
+        "node_modules/cliss/node_modules/camelcase": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+            "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/cliss/node_modules/yargs-parser": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+            "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+            "dependencies": {
+                "camelcase": "^4.1.0"
+            }
+        },
+        "node_modules/cliui": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+            "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+            "dependencies": {
+                "string-width": "^3.1.0",
+                "strip-ansi": "^5.2.0",
+                "wrap-ansi": "^5.1.0"
+            }
+        },
+        "node_modules/cliui/node_modules/ansi-regex": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+            "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/cliui/node_modules/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==",
+            "dependencies": {
+                "emoji-regex": "^7.0.1",
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/cliui/node_modules/strip-ansi": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+            "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+            "dependencies": {
+                "ansi-regex": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/clj-fuzzy": {
+            "version": "0.3.3",
+            "resolved": "https://registry.npmjs.org/clj-fuzzy/-/clj-fuzzy-0.3.3.tgz",
+            "integrity": "sha1-seU0MJHFIC28UlMoY+HEp4RX8D0="
+        },
+        "node_modules/clone-deep": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz",
+            "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
+            "dev": true,
+            "dependencies": {
+                "is-plain-object": "^2.0.4",
+                "kind-of": "^6.0.2",
+                "shallow-clone": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/clsx": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+            "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/collection-visit": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+            "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+            "dependencies": {
+                "map-visit": "^1.0.0",
+                "object-visit": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/color": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
+            "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+            "dependencies": {
+                "color-convert": "^1.9.1",
+                "color-string": "^1.5.2"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "color-name": "1.1.3"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+            "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+        },
+        "node_modules/color-string": {
+            "version": "1.5.3",
+            "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+            "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+            "dependencies": {
+                "color-name": "^1.0.0",
+                "simple-swizzle": "^0.2.2"
+            }
+        },
+        "node_modules/colors": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+            "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+            "engines": {
+                "node": ">=0.1.90"
+            }
+        },
+        "node_modules/combined-stream": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+            "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+            "dependencies": {
+                "delayed-stream": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/command-exists": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.6.tgz",
+            "integrity": "sha512-Qst/zUUNmS/z3WziPxyqjrcz09pm+2Knbs5mAZL4VAE0sSrNY1/w8+/YxeHcoBTsO6iojA6BW7eFf27Eg2MRuw=="
+        },
+        "node_modules/command-line-usage": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
+            "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
+            "dependencies": {
+                "ansi-escape-sequences": "^4.0.0",
+                "array-back": "^2.0.0",
+                "table-layout": "^0.4.2",
+                "typical": "^2.6.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/commander": {
+            "version": "2.20.3",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+            "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+        },
+        "node_modules/commondir": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+            "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+            "dev": true
+        },
+        "node_modules/component-bind": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+            "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
+        },
+        "node_modules/component-emitter": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+            "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
+        },
+        "node_modules/component-inherit": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+            "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
+        },
+        "node_modules/compress-commons": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz",
+            "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==",
+            "dependencies": {
+                "buffer-crc32": "^0.2.13",
+                "crc32-stream": "^3.0.1",
+                "normalize-path": "^3.0.0",
+                "readable-stream": "^2.3.6"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/compress-commons/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/compressible": {
+            "version": "2.0.18",
+            "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+            "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+            "dev": true,
+            "dependencies": {
+                "mime-db": ">= 1.43.0 < 2"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/compression": {
+            "version": "1.7.4",
+            "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+            "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/compression/node_modules/bytes": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+            "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/compression/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/compression/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+            "dev": true
+        },
+        "node_modules/concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+        },
+        "node_modules/concat-stream": {
+            "version": "1.6.2",
+            "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+            "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+            "engines": [
+                "node >= 0.8"
+            ],
+            "dependencies": {
+                "buffer-from": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.2.2",
+                "typedarray": "^0.0.6"
+            }
+        },
+        "node_modules/concat-stream/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/configstore": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
+            "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
+            "dependencies": {
+                "dot-prop": "^4.1.0",
+                "graceful-fs": "^4.1.2",
+                "make-dir": "^1.0.0",
+                "unique-string": "^1.0.0",
+                "write-file-atomic": "^2.0.0",
+                "xdg-basedir": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/connect-flash": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
+            "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA=",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/connect-mongo": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.3.tgz",
+            "integrity": "sha512-Vs+QZ/6X6gbCrP1Ls7Oh/wlyY6pgpbPSrUKF5yRT+zd+4GZPNbjNquxquZ+Clv2+03HBXE7T4lVM0PUcaBhihg==",
+            "dependencies": {
+                "mongodb": "^2.0.36"
+            }
+        },
+        "node_modules/connect-mongo/node_modules/mongodb": {
+            "version": "2.2.36",
+            "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz",
+            "integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==",
+            "dependencies": {
+                "es6-promise": "3.2.1",
+                "mongodb-core": "2.1.20",
+                "readable-stream": "2.2.7"
+            },
+            "engines": {
+                "node": ">=0.10.3"
+            }
+        },
+        "node_modules/connect-mongo/node_modules/process-nextick-args": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+            "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+        },
+        "node_modules/connect-mongo/node_modules/readable-stream": {
+            "version": "2.2.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
+            "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
+            "dependencies": {
+                "buffer-shims": "~1.0.0",
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.1",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~1.0.6",
+                "string_decoder": "~1.0.0",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "node_modules/connect-mongo/node_modules/string_decoder": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+            "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/console-browserify": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+            "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+            "dev": true
+        },
+        "node_modules/console-control-strings": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+            "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+        },
+        "node_modules/constantinople": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
+            "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
+            "dependencies": {
+                "@types/babel-types": "^7.0.0",
+                "@types/babylon": "^6.16.2",
+                "babel-types": "^6.26.0",
+                "babylon": "^6.18.0"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/content-disposition": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+            "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+            "dependencies": {
+                "safe-buffer": "5.1.2"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/convert-source-map": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+            "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+            "dependencies": {
+                "safe-buffer": "~5.1.1"
+            }
+        },
+        "node_modules/cookie": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+            "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/cookie-parser": {
+            "version": "1.4.5",
+            "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
+            "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
+            "dependencies": {
+                "cookie": "0.4.0",
+                "cookie-signature": "1.0.6"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/cookie-session": {
+            "version": "2.0.0-rc.1",
+            "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-2.0.0-rc.1.tgz",
+            "integrity": "sha512-zg80EsLe7S1J4y0XxV7SZ8Fbi90ZZoampuX2bfYDOvJfc//98sSlZC41YDzTTjtVbeU1VlVdBbldXOOyi5xzEw==",
+            "dependencies": {
+                "cookies": "0.8.0",
+                "debug": "3.2.6",
+                "on-headers": "~1.0.2",
+                "safe-buffer": "5.2.0"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/cookie-session/node_modules/safe-buffer": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+            "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+        },
+        "node_modules/cookie-signature": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+            "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+        },
+        "node_modules/cookies": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
+            "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
+            "dependencies": {
+                "depd": "~2.0.0",
+                "keygrip": "~1.1.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/cookies/node_modules/depd": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+            "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/copy-concurrently/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/copy-descriptor": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+            "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/copy-webpack-plugin": {
+            "version": "4.6.0",
+            "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz",
+            "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==",
+            "dev": true,
+            "dependencies": {
+                "cacache": "^10.0.4",
+                "find-cache-dir": "^1.0.0",
+                "globby": "^7.1.1",
+                "is-glob": "^4.0.0",
+                "loader-utils": "^1.1.0",
+                "minimatch": "^3.0.4",
+                "p-limit": "^1.0.0",
+                "serialize-javascript": "^1.4.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/copy-webpack-plugin/node_modules/p-limit": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+            "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+            "dev": true,
+            "dependencies": {
+                "p-try": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/copy-webpack-plugin/node_modules/p-try": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+            "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/core-js": {
+            "version": "1.2.7",
+            "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+            "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
+        },
+        "node_modules/core-js-pure": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz",
+            "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==",
+            "hasInstallScript": true
+        },
+        "node_modules/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="
+        },
+        "node_modules/cors": {
+            "version": "2.8.5",
+            "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+            "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+            "dependencies": {
+                "object-assign": "^4",
+                "vary": "^1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/cosmiconfig": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+            "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+            "dependencies": {
+                "@types/parse-json": "^4.0.0",
+                "import-fresh": "^3.1.0",
+                "parse-json": "^5.0.0",
+                "path-type": "^4.0.0",
+                "yaml": "^1.7.2"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/crc": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
+            "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
+            "dependencies": {
+                "buffer": "^5.1.0"
+            }
+        },
+        "node_modules/crc32-stream": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz",
+            "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==",
+            "dependencies": {
+                "crc": "^3.4.4",
+                "readable-stream": "^3.4.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/create-ecdh": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+            "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+            "dev": true,
+            "dependencies": {
+                "bn.js": "^4.1.0",
+                "elliptic": "^6.5.3"
+            }
+        },
+        "node_modules/create-ecdh/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/create-emotion": {
+            "version": "10.0.27",
+            "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.27.tgz",
+            "integrity": "sha512-fIK73w82HPPn/RsAij7+Zt8eCE8SptcJ3WoRMfxMtjteYxud8GDTKKld7MYwAX2TVhrw29uR1N/bVGxeStHILg==",
+            "dependencies": {
+                "@emotion/cache": "^10.0.27",
+                "@emotion/serialize": "^0.11.15",
+                "@emotion/sheet": "0.9.4",
+                "@emotion/utils": "0.11.3"
+            }
+        },
+        "node_modules/create-error-class": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+            "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+            "dependencies": {
+                "capture-stack-trace": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "cipher-base": "^1.0.1",
+                "inherits": "^2.0.1",
+                "md5.js": "^1.3.4",
+                "ripemd160": "^2.0.1",
+                "sha.js": "^2.4.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/create-react-context": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
+            "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
+            "dependencies": {
+                "fbjs": "^0.8.0",
+                "gud": "^1.0.0"
+            }
+        },
+        "node_modules/cross-env": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz",
+            "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==",
+            "dev": true,
+            "dependencies": {
+                "cross-spawn": "^6.0.5"
+            },
+            "bin": {
+                "cross-env": "dist/bin/cross-env.js",
+                "cross-env-shell": "dist/bin/cross-env-shell.js"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/cross-env/node_modules/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,
+            "dependencies": {
+                "nice-try": "^1.0.4",
+                "path-key": "^2.0.1",
+                "semver": "^5.5.0",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            },
+            "engines": {
+                "node": ">=4.8"
+            }
+        },
+        "node_modules/cross-fetch": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz",
+            "integrity": "sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==",
+            "dependencies": {
+                "node-fetch": "2.6.0",
+                "whatwg-fetch": "3.0.0"
+            }
+        },
+        "node_modules/cross-fetch/node_modules/node-fetch": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
+            "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
+            "engines": {
+                "node": "4.x || >=6.0.0"
+            }
+        },
+        "node_modules/cross-spawn": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+            "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+            "dependencies": {
+                "lru-cache": "^4.0.1",
+                "which": "^1.2.9"
+            }
+        },
+        "node_modules/cross-spawn/node_modules/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==",
+            "dependencies": {
+                "pseudomap": "^1.0.2",
+                "yallist": "^2.1.2"
+            }
+        },
+        "node_modules/cross-spawn/node_modules/yallist": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+            "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/crypto-random-string": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+            "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/css-box-model": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
+            "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
+            "dependencies": {
+                "tiny-invariant": "^1.0.6"
+            }
+        },
+        "node_modules/css-color-keywords": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+            "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/css-in-js-utils": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz",
+            "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==",
+            "dependencies": {
+                "hyphenate-style-name": "^1.0.2",
+                "isobject": "^3.0.1"
+            }
+        },
+        "node_modules/css-loader": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-2.1.1.tgz",
+            "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==",
+            "dev": true,
+            "dependencies": {
+                "camelcase": "^5.2.0",
+                "icss-utils": "^4.1.0",
+                "loader-utils": "^1.2.3",
+                "normalize-path": "^3.0.0",
+                "postcss": "^7.0.14",
+                "postcss-modules-extract-imports": "^2.0.0",
+                "postcss-modules-local-by-default": "^2.0.6",
+                "postcss-modules-scope": "^2.1.0",
+                "postcss-modules-values": "^2.0.0",
+                "postcss-value-parser": "^3.3.0",
+                "schema-utils": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/css-loader/node_modules/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,
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/css-select": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+            "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+            "dependencies": {
+                "boolbase": "~1.0.0",
+                "css-what": "2.1",
+                "domutils": "1.5.1",
+                "nth-check": "~1.0.1"
+            }
+        },
+        "node_modules/css-select/node_modules/domutils": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+            "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+            "dependencies": {
+                "dom-serializer": "0",
+                "domelementtype": "1"
+            }
+        },
+        "node_modules/css-to-react-native": {
+            "version": "2.3.2",
+            "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz",
+            "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==",
+            "dependencies": {
+                "camelize": "^1.0.0",
+                "css-color-keywords": "^1.0.0",
+                "postcss-value-parser": "^3.3.0"
+            }
+        },
+        "node_modules/css-vendor": {
+            "version": "2.0.8",
+            "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+            "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
+            "dependencies": {
+                "@babel/runtime": "^7.8.3",
+                "is-in-browser": "^1.0.2"
+            }
+        },
+        "node_modules/css-what": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+            "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/cssesc": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+            "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+            "dev": true,
+            "bin": {
+                "cssesc": "bin/cssesc"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/cssom": {
+            "version": "0.4.4",
+            "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+            "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+            "dev": true
+        },
+        "node_modules/cssstyle": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz",
+            "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==",
+            "dev": true,
+            "dependencies": {
+                "cssom": "~0.3.6"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/cssstyle/node_modules/cssom": {
+            "version": "0.3.8",
+            "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+            "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+            "dev": true
+        },
+        "node_modules/csstype": {
+            "version": "2.6.10",
+            "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
+            "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
+        },
+        "node_modules/currently-unhandled": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+            "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+            "dependencies": {
+                "array-find-index": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/custom-event": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+            "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU="
+        },
+        "node_modules/cyclist": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+            "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+            "dev": true
+        },
+        "node_modules/d": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+            "dev": true,
+            "dependencies": {
+                "es5-ext": "^0.10.50",
+                "type": "^1.0.1"
+            }
+        },
+        "node_modules/d3-array": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
+            "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
+        },
+        "node_modules/d3-axis": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-2.0.0.tgz",
+            "integrity": "sha512-9nzB0uePtb+u9+dWir+HTuEAKJOEUYJoEwbJPsZ1B4K3iZUgzJcSENQ05Nj7S4CIfbZZ8/jQGoUzGKFznBhiiQ=="
+        },
+        "node_modules/d3-color": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+            "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
+        },
+        "node_modules/d3-dispatch": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
+            "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
+        },
+        "node_modules/d3-drag": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
+            "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-selection": "2"
+            }
+        },
+        "node_modules/d3-ease": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
+            "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
+        },
+        "node_modules/d3-format": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+            "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+        },
+        "node_modules/d3-interpolate": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+            "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+            "dependencies": {
+                "d3-color": "1 - 2"
+            }
+        },
+        "node_modules/d3-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+            "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+        },
+        "node_modules/d3-scale": {
+            "version": "3.2.3",
+            "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz",
+            "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==",
+            "dependencies": {
+                "d3-array": "^2.3.0",
+                "d3-format": "1 - 2",
+                "d3-interpolate": "1.2.0 - 2",
+                "d3-time": "1 - 2",
+                "d3-time-format": "2 - 3"
+            }
+        },
+        "node_modules/d3-scale/node_modules/d3-array": {
+            "version": "2.11.0",
+            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.11.0.tgz",
+            "integrity": "sha512-26clcwmHQEdsLv34oNKq5Ia9tQ26Y/4HqS3dQzF42QBUqymZJ+9PORcN1G52bt37NsL2ABoX4lvyYZc+A9Y0zw==",
+            "dependencies": {
+                "internmap": "^1.0.0"
+            }
+        },
+        "node_modules/d3-selection": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
+            "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
+        },
+        "node_modules/d3-shape": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.0.0.tgz",
+            "integrity": "sha512-djpGlA779ua+rImicYyyjnOjeubyhql1Jyn1HK0bTyawuH76UQRWXd+pftr67H6Fa8hSwetkgb/0id3agKWykw==",
+            "dependencies": {
+                "d3-path": "1 - 2"
+            }
+        },
+        "node_modules/d3-time": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz",
+            "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q=="
+        },
+        "node_modules/d3-time-format": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz",
+            "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
+            "dependencies": {
+                "d3-time": "1 - 2"
+            }
+        },
+        "node_modules/d3-timer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
+            "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
+        },
+        "node_modules/d3-transition": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
+            "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
+            "dependencies": {
+                "d3-color": "1 - 2",
+                "d3-dispatch": "1 - 2",
+                "d3-ease": "1 - 2",
+                "d3-interpolate": "1 - 2",
+                "d3-timer": "1 - 2"
+            }
+        },
+        "node_modules/d3-zoom": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz",
+            "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-drag": "2",
+                "d3-interpolate": "1 - 2",
+                "d3-selection": "2",
+                "d3-transition": "2"
+            }
+        },
+        "node_modules/dashdash": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+            "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+            "dependencies": {
+                "assert-plus": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/data-urls": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+            "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+            "dev": true,
+            "dependencies": {
+                "abab": "^2.0.0",
+                "whatwg-mimetype": "^2.2.0",
+                "whatwg-url": "^7.0.0"
+            }
+        },
+        "node_modules/date-fns": {
+            "version": "2.14.0",
+            "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.14.0.tgz",
+            "integrity": "sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw=="
+        },
+        "node_modules/dateformat": {
+            "version": "1.0.12",
+            "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+            "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+            "dev": true,
+            "dependencies": {
+                "get-stdin": "^4.0.1",
+                "meow": "^3.3.0"
+            },
+            "bin": {
+                "dateformat": "bin/cli.js"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/dateformat/node_modules/get-stdin": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+            "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/de-indent": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+            "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
+        },
+        "node_modules/debounce": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
+            "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
+        },
+        "node_modules/debug": {
+            "version": "3.2.6",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+            "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/decamelize": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+            "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/decompress-response": {
+            "version": "4.2.1",
+            "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+            "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+            "dependencies": {
+                "mimic-response": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/deep-eql": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+            "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+            "dependencies": {
+                "type-detect": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
+        "node_modules/deep-equal": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+            "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+            "dependencies": {
+                "is-arguments": "^1.0.4",
+                "is-date-object": "^1.0.1",
+                "is-regex": "^1.0.4",
+                "object-is": "^1.0.1",
+                "object-keys": "^1.1.1",
+                "regexp.prototype.flags": "^1.2.0"
+            }
+        },
+        "node_modules/deep-extend": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+            "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/deep-is": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+            "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+            "dev": true
+        },
+        "node_modules/deepmerge": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+            "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "execa": "^1.0.0",
+                "ip-regex": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/default-gateway/node_modules/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,
+            "dependencies": {
+                "nice-try": "^1.0.4",
+                "path-key": "^2.0.1",
+                "semver": "^5.5.0",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            },
+            "engines": {
+                "node": ">=4.8"
+            }
+        },
+        "node_modules/default-gateway/node_modules/execa": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+            "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/default-gateway/node_modules/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,
+            "dependencies": {
+                "pump": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/define-properties": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+            "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+            "dependencies": {
+                "object-keys": "^1.0.12"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/define-property": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+            "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+            "dependencies": {
+                "is-descriptor": "^1.0.2",
+                "isobject": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/define-property/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/define-property/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/define-property/node_modules/is-descriptor": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+            "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+            "dependencies": {
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/del": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+            "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+            "dev": true,
+            "dependencies": {
+                "@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"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/del/node_modules/globby": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+            "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+            "dev": true,
+            "dependencies": {
+                "array-union": "^1.0.1",
+                "glob": "^7.0.3",
+                "object-assign": "^4.0.1",
+                "pify": "^2.0.0",
+                "pinkie-promise": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/del/node_modules/globby/node_modules/pify": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+            "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/del/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/delayed-stream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/delegates": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+            "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+        },
+        "node_modules/denque": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
+            "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/depcheck": {
+            "version": "0.9.2",
+            "resolved": "https://registry.npmjs.org/depcheck/-/depcheck-0.9.2.tgz",
+            "integrity": "sha512-w5f+lSZqLJJkk58s44eOd0Vor7hLZot4PlFL0y2JsIX5LuHQ2eAjHlDVeGBD4Mj6ZQSKakvKWRRCcPlvrdU2Sg==",
+            "dependencies": {
+                "@babel/parser": "^7.7.7",
+                "@babel/traverse": "^7.7.4",
+                "builtin-modules": "^3.0.0",
+                "camelcase": "^5.3.1",
+                "cosmiconfig": "^5.2.1",
+                "debug": "^4.1.1",
+                "deps-regex": "^0.1.4",
+                "js-yaml": "^3.4.2",
+                "lodash": "^4.17.15",
+                "minimatch": "^3.0.2",
+                "node-sass-tilde-importer": "^1.0.2",
+                "please-upgrade-node": "^3.2.0",
+                "require-package-name": "^2.0.1",
+                "resolve": "^1.14.1",
+                "vue-template-compiler": "^2.6.11",
+                "walkdir": "^0.4.1",
+                "yargs": "^15.0.2"
+            },
+            "bin": {
+                "depcheck": "bin/depcheck.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/depcheck/node_modules/ansi-regex": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+            "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/ansi-styles": {
+            "version": "4.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
+            "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
+            "dependencies": {
+                "@types/color-name": "^1.1.1",
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/builtin-modules": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
+            "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/depcheck/node_modules/cliui": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+            "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+            "dependencies": {
+                "string-width": "^4.2.0",
+                "strip-ansi": "^6.0.0",
+                "wrap-ansi": "^6.2.0"
+            }
+        },
+        "node_modules/depcheck/node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/depcheck/node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
+        "node_modules/depcheck/node_modules/cosmiconfig": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+            "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+            "dependencies": {
+                "import-fresh": "^2.0.0",
+                "is-directory": "^0.3.1",
+                "js-yaml": "^3.13.1",
+                "parse-json": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/depcheck/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/depcheck/node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "node_modules/depcheck/node_modules/find-up": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+            "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+            "dependencies": {
+                "locate-path": "^5.0.0",
+                "path-exists": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/import-fresh": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+            "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+            "dependencies": {
+                "caller-path": "^2.0.0",
+                "resolve-from": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/depcheck/node_modules/is-fullwidth-code-point": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/locate-path": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+            "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+            "dependencies": {
+                "p-locate": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/p-locate": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+            "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+            "dependencies": {
+                "p-limit": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/parse-json": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+            "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+            "dependencies": {
+                "error-ex": "^1.3.1",
+                "json-parse-better-errors": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/depcheck/node_modules/path-exists": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+            "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/resolve-from": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+            "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/depcheck/node_modules/string-width": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+            "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+            "dependencies": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/strip-ansi": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+            "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+            "dependencies": {
+                "ansi-regex": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/wrap-ansi": {
+            "version": "6.2.0",
+            "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+            "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+            "dependencies": {
+                "ansi-styles": "^4.0.0",
+                "string-width": "^4.1.0",
+                "strip-ansi": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/yargs": {
+            "version": "15.3.1",
+            "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
+            "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
+            "dependencies": {
+                "cliui": "^6.0.0",
+                "decamelize": "^1.2.0",
+                "find-up": "^4.1.0",
+                "get-caller-file": "^2.0.1",
+                "require-directory": "^2.1.1",
+                "require-main-filename": "^2.0.0",
+                "set-blocking": "^2.0.0",
+                "string-width": "^4.2.0",
+                "which-module": "^2.0.0",
+                "y18n": "^4.0.0",
+                "yargs-parser": "^18.1.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/depcheck/node_modules/yargs-parser": {
+            "version": "18.1.3",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+            "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+            "dependencies": {
+                "camelcase": "^5.0.0",
+                "decamelize": "^1.2.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/depd": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+            "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/deps-regex": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz",
+            "integrity": "sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ="
+        },
+        "node_modules/des.js": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+            "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "minimalistic-assert": "^1.0.0"
+            }
+        },
+        "node_modules/destroy": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+            "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+        },
+        "node_modules/detect-file": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+            "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/detect-libc": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+            "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
+            "bin": {
+                "detect-libc": "bin/detect-libc.js"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/detect-node": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+            "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+            "dev": true
+        },
+        "node_modules/diff": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+            "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+            "engines": {
+                "node": ">=0.3.1"
+            }
+        },
+        "node_modules/diff-match-patch": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+            "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "bn.js": "^4.1.0",
+                "miller-rabin": "^4.0.0",
+                "randombytes": "^2.0.0"
+            }
+        },
+        "node_modules/diffie-hellman/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/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,
+            "dependencies": {
+                "path-type": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/dir-glob/node_modules/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,
+            "dependencies": {
+                "pify": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/dir-glob/node_modules/pify": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+            "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/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,
+            "dependencies": {
+                "ip": "^1.1.0",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "buffer-indexof": "^1.0.0"
+            }
+        },
+        "node_modules/doctypes": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
+            "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
+        },
+        "node_modules/dom-helpers": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
+            "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
+            "dependencies": {
+                "@babel/runtime": "^7.1.2"
+            }
+        },
+        "node_modules/dom-serializer": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+            "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+            "dependencies": {
+                "domelementtype": "^2.0.1",
+                "entities": "^2.0.0"
+            }
+        },
+        "node_modules/dom-serializer/node_modules/domelementtype": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
+            "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ=="
+        },
+        "node_modules/dom-serializer/node_modules/entities": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
+            "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw=="
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=0.4",
+                "npm": ">=1.2"
+            }
+        },
+        "node_modules/domelementtype": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+            "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
+        },
+        "node_modules/domexception": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+            "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+            "dev": true,
+            "dependencies": {
+                "webidl-conversions": "^4.0.2"
+            }
+        },
+        "node_modules/domhandler": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+            "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+            "dependencies": {
+                "domelementtype": "1"
+            }
+        },
+        "node_modules/domutils": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+            "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+            "dependencies": {
+                "dom-serializer": "0",
+                "domelementtype": "1"
+            }
+        },
+        "node_modules/dot-prop": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+            "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+            "dependencies": {
+                "is-obj": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/dotenv": {
+            "version": "8.2.0",
+            "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+            "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/double-bits": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/double-bits/-/double-bits-1.1.1.tgz",
+            "integrity": "sha1-WKu6RUlNpND6Nrc60RoobJGEscY="
+        },
+        "node_modules/duplexer3": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+            "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+        },
+        "node_modules/duplexify": {
+            "version": "3.7.1",
+            "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+            "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+            "dev": true,
+            "dependencies": {
+                "end-of-stream": "^1.0.0",
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "node_modules/duplexify/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/dynamic-dedupe": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/dynamic-dedupe/-/dynamic-dedupe-0.3.0.tgz",
+            "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=",
+            "dev": true,
+            "dependencies": {
+                "xtend": "^4.0.0"
+            }
+        },
+        "node_modules/ecc-jsbn": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+            "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+            "dependencies": {
+                "jsbn": "~0.1.0",
+                "safer-buffer": "^2.1.0"
+            }
+        },
+        "node_modules/ecdsa-sig-formatter": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+            "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/ee-first": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+            "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+        },
+        "node_modules/elliptic": {
+            "version": "6.5.4",
+            "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
+            "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
+            "dev": true,
+            "dependencies": {
+                "bn.js": "^4.11.9",
+                "brorand": "^1.1.0",
+                "hash.js": "^1.0.0",
+                "hmac-drbg": "^1.0.1",
+                "inherits": "^2.0.4",
+                "minimalistic-assert": "^1.0.1",
+                "minimalistic-crypto-utils": "^1.0.1"
+            }
+        },
+        "node_modules/elliptic/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/emoji-regex": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+            "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+        },
+        "node_modules/emojis-list": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+            "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/emotion": {
+            "version": "10.0.27",
+            "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.27.tgz",
+            "integrity": "sha512-2xdDzdWWzue8R8lu4G76uWX5WhyQuzATon9LmNeCy/2BHVC6dsEpfhN1a0qhELgtDVdjyEA6J8Y/VlI5ZnaH0g==",
+            "dependencies": {
+                "babel-plugin-emotion": "^10.0.27",
+                "create-emotion": "^10.0.27"
+            }
+        },
+        "node_modules/encodeurl": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+            "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/encoding": {
+            "version": "0.1.12",
+            "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+            "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+            "dependencies": {
+                "iconv-lite": "~0.4.13"
+            }
+        },
+        "node_modules/end-of-stream": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+            "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+            "dependencies": {
+                "once": "^1.4.0"
+            }
+        },
+        "node_modules/engine.io": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.1.tgz",
+            "integrity": "sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw==",
+            "dependencies": {
+                "accepts": "~1.3.4",
+                "base64id": "2.0.0",
+                "cookie": "0.3.1",
+                "debug": "~4.1.0",
+                "engine.io-parser": "~2.2.0",
+                "ws": "^7.1.2"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/engine.io-client": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.1.tgz",
+            "integrity": "sha512-RJNmA+A9Js+8Aoq815xpGAsgWH1VoSYM//2VgIiu9lNOaHFfLpTjH4tOzktBpjIs5lvOfiNY1dwf+NuU6D38Mw==",
+            "dependencies": {
+                "component-emitter": "1.2.1",
+                "component-inherit": "0.0.3",
+                "debug": "~4.1.0",
+                "engine.io-parser": "~2.2.0",
+                "has-cors": "1.1.0",
+                "indexof": "0.0.1",
+                "parseqs": "0.0.5",
+                "parseuri": "0.0.5",
+                "ws": "~6.1.0",
+                "xmlhttprequest-ssl": "~1.5.4",
+                "yeast": "0.1.2"
+            }
+        },
+        "node_modules/engine.io-client/node_modules/component-emitter": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+            "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+        },
+        "node_modules/engine.io-client/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/engine.io-client/node_modules/ws": {
+            "version": "6.1.4",
+            "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
+            "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+            "dependencies": {
+                "async-limiter": "~1.0.0"
+            }
+        },
+        "node_modules/engine.io-parser": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
+            "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
+            "dependencies": {
+                "after": "0.8.2",
+                "arraybuffer.slice": "~0.0.7",
+                "base64-arraybuffer": "0.1.5",
+                "blob": "0.0.5",
+                "has-binary2": "~1.0.2"
+            }
+        },
+        "node_modules/engine.io/node_modules/cookie": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+            "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/engine.io/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/enhanced-resolve": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
+            "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==",
+            "dev": true,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "memory-fs": "^0.5.0",
+                "tapable": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/entities": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+            "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
+        },
+        "node_modules/equation-editor-react": {
+            "resolved": "git+ssh://git@github.com/bobzel/equation-editor-react.git#75915e852b4b36a6a4cd3e1cbc80598da6b65227",
+            "dependencies": {
+                "jquery": "^3.4.1",
+                "mathquill": "^0.10.1-a"
+            }
+        },
+        "node_modules/errno": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+            "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+            "dev": true,
+            "dependencies": {
+                "prr": "~1.0.1"
+            },
+            "bin": {
+                "errno": "cli.js"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "is-arrayish": "^0.2.1"
+            }
+        },
+        "node_modules/es-abstract": {
+            "version": "1.17.5",
+            "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
+            "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
+            "dependencies": {
+                "es-to-primitive": "^1.2.1",
+                "function-bind": "^1.1.1",
+                "has": "^1.0.3",
+                "has-symbols": "^1.0.1",
+                "is-callable": "^1.1.5",
+                "is-regex": "^1.0.5",
+                "object-inspect": "^1.7.0",
+                "object-keys": "^1.1.1",
+                "object.assign": "^4.1.0",
+                "string.prototype.trimleft": "^2.1.1",
+                "string.prototype.trimright": "^2.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-to-primitive": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+            "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+            "dependencies": {
+                "is-callable": "^1.1.4",
+                "is-date-object": "^1.0.1",
+                "is-symbol": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es5-ext": {
+            "version": "0.10.53",
+            "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz",
+            "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==",
+            "dev": true,
+            "dependencies": {
+                "es6-iterator": "~2.0.3",
+                "es6-symbol": "~3.1.3",
+                "next-tick": "~1.0.0"
+            }
+        },
+        "node_modules/es6-iterator": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+            "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+            "dev": true,
+            "dependencies": {
+                "d": "1",
+                "es5-ext": "^0.10.35",
+                "es6-symbol": "^3.1.1"
+            }
+        },
+        "node_modules/es6-promise": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
+            "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q="
+        },
+        "node_modules/es6-symbol": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
+            "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
+            "dev": true,
+            "dependencies": {
+                "d": "^1.0.1",
+                "ext": "^1.1.2"
+            }
+        },
+        "node_modules/escape-html": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+            "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/escodegen": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
+            "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
+            "dev": true,
+            "dependencies": {
+                "esprima": "^4.0.1",
+                "estraverse": "^4.2.0",
+                "esutils": "^2.0.2",
+                "optionator": "^0.8.1"
+            },
+            "bin": {
+                "escodegen": "bin/escodegen.js",
+                "esgenerate": "bin/esgenerate.js"
+            },
+            "engines": {
+                "node": ">=4.0"
+            },
+            "optionalDependencies": {
+                "source-map": "~0.6.1"
+            }
+        },
+        "node_modules/escodegen/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "esrecurse": "^4.1.0",
+                "estraverse": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/esprima": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+            "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+            "bin": {
+                "esparse": "bin/esparse.js",
+                "esvalidate": "bin/esvalidate.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/esrecurse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+            "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+            "dev": true,
+            "dependencies": {
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esrecurse/node_modules/estraverse": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+            "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/estraverse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esutils": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/etag": {
+            "version": "1.8.1",
+            "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+            "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/event-target-shim": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+            "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/eventemitter3": {
+            "version": "4.0.4",
+            "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz",
+            "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==",
+            "dev": true
+        },
+        "node_modules/events": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
+            "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.x"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "original": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "md5.js": "^1.3.4",
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/execa": {
+            "version": "0.7.0",
+            "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+            "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+            "dependencies": {
+                "cross-spawn": "^5.0.1",
+                "get-stream": "^3.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"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/execa/node_modules/cross-spawn": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+            "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+            "dependencies": {
+                "lru-cache": "^4.0.1",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            }
+        },
+        "node_modules/execa/node_modules/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==",
+            "dependencies": {
+                "pseudomap": "^1.0.2",
+                "yallist": "^2.1.2"
+            }
+        },
+        "node_modules/execa/node_modules/yallist": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+            "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+        },
+        "node_modules/exenv": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
+            "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
+        },
+        "node_modules/exeq": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/exeq/-/exeq-2.4.0.tgz",
+            "integrity": "sha1-Td8qaEZIxCeteZNJzzO9dTWPiEo=",
+            "dependencies": {
+                "bluebird": "^3.0.3",
+                "native-or-bluebird": "^1.2.0"
+            },
+            "engines": {
+                "node": ">= 0.10.0"
+            }
+        },
+        "node_modules/exif": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
+            "integrity": "sha1-YKYmaAdlQst+T1cZnUrG830sX0o=",
+            "dependencies": {
+                "debug": "^2.2"
+            }
+        },
+        "node_modules/exif/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/exif/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/expand-brackets": {
+            "version": "2.1.4",
+            "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+            "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-brackets/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/expand-brackets/node_modules/define-property": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+            "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+            "dependencies": {
+                "is-descriptor": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-brackets/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-brackets/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-brackets/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/expand-template": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+            "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/expand-tilde": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+            "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+            "dev": true,
+            "dependencies": {
+                "homedir-polyfill": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/express": {
+            "version": "4.17.1",
+            "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+            "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.10.0"
+            }
+        },
+        "node_modules/express-flash": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
+            "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
+            "dependencies": {
+                "connect-flash": "0.1.x"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/express-session": {
+            "version": "1.17.1",
+            "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
+            "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
+            "dependencies": {
+                "cookie": "0.4.0",
+                "cookie-signature": "1.0.6",
+                "debug": "2.6.9",
+                "depd": "~2.0.0",
+                "on-headers": "~1.0.2",
+                "parseurl": "~1.3.3",
+                "safe-buffer": "5.2.0",
+                "uid-safe": "~2.1.5"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/express-session/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/express-session/node_modules/depd": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+            "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/express-session/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/express-session/node_modules/safe-buffer": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+            "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+        },
+        "node_modules/express-validator": {
+            "version": "5.3.1",
+            "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-5.3.1.tgz",
+            "integrity": "sha512-g8xkipBF6VxHbO1+ksC7nxUU7+pWif0+OZXjZTybKJ/V0aTVhuCoHbyhIPgSYVldwQLocGExPtB2pE0DqK4jsw==",
+            "dependencies": {
+                "lodash": "^4.17.10",
+                "validator": "^10.4.0"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/express/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/express/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/express/node_modules/qs": {
+            "version": "6.7.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+            "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/expressjs": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/expressjs/-/expressjs-1.0.1.tgz",
+            "integrity": "sha1-IgMoRpoY31rWFeK3oM6ZXxf7ru8="
+        },
+        "node_modules/ext": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz",
+            "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",
+            "dev": true,
+            "dependencies": {
+                "type": "^2.0.0"
+            }
+        },
+        "node_modules/ext/node_modules/type": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz",
+            "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==",
+            "dev": true
+        },
+        "node_modules/extend": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+            "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+        },
+        "node_modules/extend-shallow": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+            "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+            "dependencies": {
+                "assign-symbols": "^1.0.0",
+                "is-extendable": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+            "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/define-property": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+            "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+            "dependencies": {
+                "is-descriptor": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/is-descriptor": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+            "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+            "dependencies": {
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extglob/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/extract-zip": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+            "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+            "dependencies": {
+                "debug": "^4.1.1",
+                "get-stream": "^5.1.0",
+                "yauzl": "^2.10.0"
+            },
+            "bin": {
+                "extract-zip": "cli.js"
+            },
+            "engines": {
+                "node": ">= 10.17.0"
+            },
+            "optionalDependencies": {
+                "@types/yauzl": "^2.9.1"
+            }
+        },
+        "node_modules/extract-zip/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/extract-zip/node_modules/get-stream": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+            "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+            "dependencies": {
+                "pump": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/extsprintf": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+            "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+            "engines": [
+                "node >=0.6.0"
+            ]
+        },
+        "node_modules/fast-deep-equal": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
+            "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
+        },
+        "node_modules/fast-json-stable-stringify": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+            "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+        },
+        "node_modules/fast-levenshtein": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+            "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+            "dev": true
+        },
+        "node_modules/fast-text-encoding": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.2.tgz",
+            "integrity": "sha512-5rQdinSsycpzvAoHga2EDn+LRX1d5xLFsuNG0Kg61JrAT/tASXcLL0nf/33v+sAxlQcfYmWbTURa1mmAf55jGw=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "websocket-driver": ">=0.5.1"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/fbjs": {
+            "version": "0.8.17",
+            "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
+            "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
+            "dependencies": {
+                "core-js": "^1.0.0",
+                "isomorphic-fetch": "^2.1.1",
+                "loose-envify": "^1.0.0",
+                "object-assign": "^4.1.0",
+                "promise": "^7.1.1",
+                "setimmediate": "^1.0.5",
+                "ua-parser-js": "^0.7.18"
+            }
+        },
+        "node_modules/fd-slicer": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+            "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+            "dependencies": {
+                "pend": "~1.2.0"
+            }
+        },
+        "node_modules/figgy-pudding": {
+            "version": "3.5.2",
+            "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+            "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+            "dev": true
+        },
+        "node_modules/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,
+            "dependencies": {
+                "loader-utils": "^1.0.2",
+                "schema-utils": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/file-loader/node_modules/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,
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/file-saver": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz",
+            "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw=="
+        },
+        "node_modules/file-uri-to-path": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+            "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+            "optional": true
+        },
+        "node_modules/fill-range": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+            "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+            "dependencies": {
+                "extend-shallow": "^2.0.1",
+                "is-number": "^3.0.0",
+                "repeat-string": "^1.6.1",
+                "to-regex-range": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/fill-range/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/fill-range/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/finalhandler": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+            "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/finalhandler/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/finalhandler/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/find": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/find/-/find-0.1.7.tgz",
+            "integrity": "sha1-yGyHrxqxjyIrvjjeyGy8dg0Wpvs=",
+            "dependencies": {
+                "traverse-chain": "~0.1.0"
+            }
+        },
+        "node_modules/find-cache-dir": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+            "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+            "dev": true,
+            "dependencies": {
+                "commondir": "^1.0.1",
+                "make-dir": "^1.0.0",
+                "pkg-dir": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/find-in-files": {
+            "version": "0.5.0",
+            "resolved": "https://registry.npmjs.org/find-in-files/-/find-in-files-0.5.0.tgz",
+            "integrity": "sha512-VraTc6HdtdSHmAp0yJpAy20yPttGKzyBWc7b7FPnnsX9TOgmKx0g9xajizpF/iuu4IvNK4TP0SpyBT9zAlwG+g==",
+            "dependencies": {
+                "find": "^0.1.5",
+                "q": "^1.0.1"
+            }
+        },
+        "node_modules/find-parent-dir": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz",
+            "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ="
+        },
+        "node_modules/find-root": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+            "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+        },
+        "node_modules/find-up": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+            "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+            "dependencies": {
+                "locate-path": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/findup-sync": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+            "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+            "dev": true,
+            "dependencies": {
+                "detect-file": "^1.0.0",
+                "is-glob": "^4.0.0",
+                "micromatch": "^3.0.4",
+                "resolve-dir": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/fit-curve": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/fit-curve/-/fit-curve-0.1.7.tgz",
+            "integrity": "sha512-Md3b3ReA/qJwwYvKXeHpOV1fhPqwhJ9/29zc9lfi8ijyg00J0S9C7+5XMZDFhlDAKbwOvVgBxVIG1EHoMSC3vw=="
+        },
+        "node_modules/flat": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
+            "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
+            "dependencies": {
+                "is-buffer": "~2.0.3"
+            },
+            "bin": {
+                "flat": "cli.js"
+            }
+        },
+        "node_modules/flexlayout-react": {
+            "version": "0.3.11",
+            "resolved": "https://registry.npmjs.org/flexlayout-react/-/flexlayout-react-0.3.11.tgz",
+            "integrity": "sha512-V+rEfyYJBqNk9oBgotPoXg8rmom4/ji9Mvr6f7T8sIJs83RuyK1D3oOrya2ydZIUCP2T6BIvj7rFTmRRkzpU8w=="
+        },
+        "node_modules/fluent-ffmpeg": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
+            "integrity": "sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=",
+            "dependencies": {
+                "async": ">=0.2.9",
+                "which": "^1.1.1"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.3.6"
+            }
+        },
+        "node_modules/flush-write-stream/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/follow-redirects": {
+            "version": "1.12.1",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
+            "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==",
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/for-each-property": {
+            "version": "0.0.4",
+            "resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz",
+            "integrity": "sha1-z6hXrsFCLh0Sb/CHhPz2Jim8g/Y=",
+            "dependencies": {
+                "get-prototype-chain": "^1.0.1"
+            }
+        },
+        "node_modules/for-each-property-deep": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/for-each-property-deep/-/for-each-property-deep-0.0.3.tgz",
+            "integrity": "sha1-MTCaSvw4qcygbxsiP1PWSm0IP60=",
+            "dependencies": {
+                "for-each-property": "0.0.4"
+            }
+        },
+        "node_modules/for-in": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+            "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/forever-agent": {
+            "version": "0.6.1",
+            "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+            "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/fork-ts-checker-webpack-plugin": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-1.6.0.tgz",
+            "integrity": "sha512-vqOY5gakcoon2s12V7MMe01OPwfgqulUWFzm+geQaPPOBKjW1I7aqqoBVlU0ECn97liMB0ECs16pRdIGe9qdRw==",
+            "dev": true,
+            "dependencies": {
+                "babel-code-frame": "^6.22.0",
+                "chalk": "^2.4.1",
+                "chokidar": "^2.0.4",
+                "micromatch": "^3.1.10",
+                "minimatch": "^3.0.4",
+                "semver": "^5.6.0",
+                "tapable": "^1.0.0",
+                "worker-rpc": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=6.11.5",
+                "yarn": ">=1.0.0"
+            }
+        },
+        "node_modules/form-data": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+            "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+            "dev": true,
+            "dependencies": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "^1.0.6",
+                "mime-types": "^2.1.12"
+            },
+            "engines": {
+                "node": ">= 0.12"
+            }
+        },
+        "node_modules/formidable": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
+            "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q=="
+        },
+        "node_modules/forwarded": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+            "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/fragment-cache": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+            "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+            "dependencies": {
+                "map-cache": "^0.2.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/fresh": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+            "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/from2": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+            "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0"
+            }
+        },
+        "node_modules/from2/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/fs-constants": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+        },
+        "node_modules/fs-extra": {
+            "version": "0.26.7",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
+            "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "jsonfile": "^2.1.0",
+                "klaw": "^1.0.0",
+                "path-is-absolute": "^1.0.0",
+                "rimraf": "^2.2.8"
+            }
+        },
+        "node_modules/fs-extra/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/fs-minipass": {
+            "version": "1.2.7",
+            "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+            "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+            "dependencies": {
+                "minipass": "^2.6.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "iferr": "^0.1.5",
+                "imurmurhash": "^0.1.4",
+                "readable-stream": "1 || 2"
+            }
+        },
+        "node_modules/fs-write-stream-atomic/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+        },
+        "node_modules/fsevents": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz",
+            "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==",
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+            }
+        },
+        "node_modules/fstream": {
+            "version": "1.0.12",
+            "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+            "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "inherits": "~2.0.0",
+                "mkdirp": ">=0.5 0",
+                "rimraf": "2"
+            },
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/fstream/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/function-bind": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+        },
+        "node_modules/function-plot": {
+            "version": "1.22.7",
+            "resolved": "https://registry.npmjs.org/function-plot/-/function-plot-1.22.7.tgz",
+            "integrity": "sha512-rB6FeVqvgNECmt5PhIvFFEOyEjM9AWLIpMkj9Nzbzq9f81Irgn3ZrXAuv5+qnuzM99jPL7ZM4kK3+ImiKXcSHA==",
+            "dependencies": {
+                "built-in-math-eval": "^0.3.0",
+                "clamp": "^1.0.1",
+                "d3-axis": "^2.0.0",
+                "d3-color": "^2.0.0",
+                "d3-format": "^2.0.0",
+                "d3-interpolate": "^2.0.1",
+                "d3-scale": "^3.2.2",
+                "d3-selection": "^2.0.0",
+                "d3-shape": "^2.0.0",
+                "d3-zoom": "^2.0.0",
+                "interval-arithmetic-eval": "^0.4.7"
+            }
+        },
+        "node_modules/gauge": {
+            "version": "2.7.4",
+            "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+            "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/gauge/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/gauge/node_modules/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=",
+            "dependencies": {
+                "number-is-nan": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/gauge/node_modules/string-width": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+            "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+            "dependencies": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/gauge/node_modules/strip-ansi": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+            "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/gaxios": {
+            "version": "2.3.4",
+            "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.4.tgz",
+            "integrity": "sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA==",
+            "dependencies": {
+                "abort-controller": "^3.0.0",
+                "extend": "^3.0.2",
+                "https-proxy-agent": "^5.0.0",
+                "is-stream": "^2.0.0",
+                "node-fetch": "^2.3.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/gaxios/node_modules/is-stream": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+            "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/gaxios/node_modules/node-fetch": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
+            "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
+            "engines": {
+                "node": "4.x || >=6.0.0"
+            }
+        },
+        "node_modules/gaze": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+            "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+            "dependencies": {
+                "globule": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/gcp-metadata": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-2.0.4.tgz",
+            "integrity": "sha512-p1lXhJvcKvJHWfQXhkd4Za1kyXRsGZA0JH7Cjs07W9hrg84d/j5tqQhbGewlSLx9gNyuQUid69uLux48YbggLg==",
+            "dependencies": {
+                "gaxios": "^2.0.1",
+                "json-bigint": "^0.3.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": "6.* || 8.* || >= 10.*"
+            }
+        },
+        "node_modules/get-func-name": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+            "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/get-node-dimensions": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz",
+            "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ=="
+        },
+        "node_modules/get-prototype-chain": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/get-prototype-chain/-/get-prototype-chain-1.0.1.tgz",
+            "integrity": "sha1-oXGhFeoeSQbG7ThDofABwYUQQW8=",
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/get-stdin": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+            "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/get-stream": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+            "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/get-value": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+            "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/getpass": {
+            "version": "0.1.7",
+            "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+            "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+            "dependencies": {
+                "assert-plus": "^1.0.0"
+            }
+        },
+        "node_modules/github-from-package": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+            "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
+        },
+        "node_modules/glob": {
+            "version": "7.1.6",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+            "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/glob-parent": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+            "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+            "dependencies": {
+                "is-glob": "^3.1.0",
+                "path-dirname": "^1.0.0"
+            }
+        },
+        "node_modules/glob-parent/node_modules/is-glob": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+            "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+            "dependencies": {
+                "is-extglob": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/global-dirs": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+            "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+            "dependencies": {
+                "ini": "^1.3.4"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/global-modules": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+            "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+            "dev": true,
+            "dependencies": {
+                "global-prefix": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/global-modules/node_modules/global-prefix": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+            "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+            "dev": true,
+            "dependencies": {
+                "ini": "^1.3.5",
+                "kind-of": "^6.0.2",
+                "which": "^1.3.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/global-prefix": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+            "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+            "dev": true,
+            "dependencies": {
+                "expand-tilde": "^2.0.2",
+                "homedir-polyfill": "^1.0.1",
+                "ini": "^1.3.4",
+                "is-windows": "^1.0.1",
+                "which": "^1.2.14"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/globals": {
+            "version": "11.12.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+            "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/globby": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+            "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/globby/node_modules/pify": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+            "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/globule": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
+            "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
+            "dependencies": {
+                "glob": "~7.1.1",
+                "lodash": "~4.17.12",
+                "minimatch": "~3.0.2"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/golden-layout": {
+            "version": "1.5.9",
+            "resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-1.5.9.tgz",
+            "integrity": "sha1-o5vB9qZ+b4hreXwBbdkk6UJrp38=",
+            "dependencies": {
+                "jquery": "*"
+            }
+        },
+        "node_modules/google-auth-library": {
+            "version": "4.2.6",
+            "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-4.2.6.tgz",
+            "integrity": "sha512-oJ6tCA9rbsYeIVY+mcLPFHa2hatz3XO6idYIrlI/KhhlMxZrO3tKyU8O2Pxu5KnSBBP7Wj4HtbM1LLKngNFaFw==",
+            "dependencies": {
+                "arrify": "^2.0.0",
+                "base64-js": "^1.3.0",
+                "fast-text-encoding": "^1.0.0",
+                "gaxios": "^2.0.0",
+                "gcp-metadata": "^2.0.0",
+                "gtoken": "^3.0.0",
+                "jws": "^3.1.5",
+                "lru-cache": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/google-maps-react": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/google-maps-react/-/google-maps-react-2.0.6.tgz",
+            "integrity": "sha512-M8Eo9WndfQEfxcmm6yRq03qdJgw1x6rQmJ9DN+a+xPQ3K7yNDGkVDbinrf4/8vcox7nELbeopbm4bpefKewWfQ=="
+        },
+        "node_modules/google-p12-pem": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.4.tgz",
+            "integrity": "sha512-S4blHBQWZRnEW44OcR7TL9WR+QCqByRvhNDZ/uuQfpxywfupikf/miba8js1jZi6ZOGv5slgSuoshCWh6EMDzg==",
+            "dependencies": {
+                "node-forge": "^0.9.0"
+            },
+            "bin": {
+                "gp12-pem": "build/src/bin/gp12-pem.js"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/googleapis": {
+            "version": "40.0.1",
+            "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-40.0.1.tgz",
+            "integrity": "sha512-B6qZVCautOOspEhru9GZ814I+ztkGWyA4ZEUfaXwXHBruX/HAWqedbsuUEx1w3nCECywK/FLTNUdcbH9zpaMaw==",
+            "dependencies": {
+                "google-auth-library": "^4.0.0",
+                "googleapis-common": "^2.0.2"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/googleapis-common": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-2.0.4.tgz",
+            "integrity": "sha512-8RRkxr24v1jIKCC1onFWA8RGnwFV55m3Qpil9DLX1yLc9e5qvOJsRoDOhhD2e7jFRONYEhT/BzT8vJZANqSr9w==",
+            "dependencies": {
+                "extend": "^3.0.2",
+                "gaxios": "^2.0.1",
+                "google-auth-library": "^4.2.5",
+                "qs": "^6.7.0",
+                "url-template": "^2.0.8",
+                "uuid": "^3.3.2"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/googleapis-common/node_modules/qs": {
+            "version": "6.9.3",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz",
+            "integrity": "sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/googlephotos": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/googlephotos/-/googlephotos-0.2.5.tgz",
+            "integrity": "sha512-XPmD3gu8aMVuwauKVzzahD2Vn8Cn8WtBRGgSF5J9A85Fn6N2GM0OToxWbEoTfyKahK+ryGHGcIYzDX98ndxE9g==",
+            "dependencies": {
+                "lodash.chunk": "^4.2.0",
+                "request": "^2.86.0",
+                "request-promise": "^4.2.2"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/got": {
+            "version": "6.7.1",
+            "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
+            "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+            "dependencies": {
+                "create-error-class": "^3.0.0",
+                "duplexer3": "^0.1.4",
+                "get-stream": "^3.0.0",
+                "is-redirect": "^1.0.0",
+                "is-retry-allowed": "^1.0.0",
+                "is-stream": "^1.0.0",
+                "lowercase-keys": "^1.0.0",
+                "safe-buffer": "^5.0.1",
+                "timed-out": "^4.0.0",
+                "unzip-response": "^2.0.1",
+                "url-parse-lax": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/graceful-fs": {
+            "version": "4.2.4",
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+            "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
+        },
+        "node_modules/growl": {
+            "version": "1.10.5",
+            "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+            "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+            "engines": {
+                "node": ">=4.x"
+            }
+        },
+        "node_modules/growly": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+            "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+            "dev": true
+        },
+        "node_modules/gtoken": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-3.0.2.tgz",
+            "integrity": "sha512-BOBi6Zz31JfxhSHRZBIDdbwIbOPyux10WxJHdx8wz/FMP1zyN1xFrsAWsgcLe5ww5v/OZu/MePUEZAjgJXSauA==",
+            "dependencies": {
+                "gaxios": "^2.0.0",
+                "google-p12-pem": "^2.0.0",
+                "jws": "^3.1.5",
+                "mime": "^2.2.0"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/gtoken/node_modules/mime": {
+            "version": "2.4.4",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
+            "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/gud": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+            "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+        },
+        "node_modules/handle-thing": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+            "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+            "dev": true
+        },
+        "node_modules/har-schema": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+            "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "ajv": "^6.5.5",
+                "har-schema": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/has": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+            "dependencies": {
+                "function-bind": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/has-ansi": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+            "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/has-ansi/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/has-binary2": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+            "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+            "dependencies": {
+                "isarray": "2.0.1"
+            }
+        },
+        "node_modules/has-binary2/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
+        },
+        "node_modules/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="
+        },
+        "node_modules/has-flag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+            "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/has-symbols": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+            "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/has-unicode": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+            "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+        },
+        "node_modules/has-value": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+            "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+            "dependencies": {
+                "get-value": "^2.0.6",
+                "has-values": "^1.0.0",
+                "isobject": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "is-number": "^3.0.0",
+                "kind-of": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/has-values/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/has-values/node_modules/kind-of": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+            "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/hash-base": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+            "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.6.0",
+                "safe-buffer": "^5.2.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/hash-base/node_modules/safe-buffer": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+            "dev": true
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "minimalistic-assert": "^1.0.1"
+            }
+        },
+        "node_modules/he": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+            "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+            "bin": {
+                "he": "bin/he"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "hash.js": "^1.0.3",
+                "minimalistic-assert": "^1.0.0",
+                "minimalistic-crypto-utils": "^1.0.1"
+            }
+        },
+        "node_modules/hoist-non-react-statics": {
+            "version": "3.3.2",
+            "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+            "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+            "dependencies": {
+                "react-is": "^16.7.0"
+            }
+        },
+        "node_modules/homedir-polyfill": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+            "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+            "dev": true,
+            "dependencies": {
+                "parse-passwd": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/hosted-git-info": {
+            "version": "2.8.8",
+            "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+            "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
+        },
+        "node_modules/howler": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/howler/-/howler-2.2.0.tgz",
+            "integrity": "sha512-sGPkrAQy7jh5mNDbkRNG0F82R2HFDYNsQXBcX4smXQT0y0F4UMsa/+jXaGwWvcrajWr2tDB7JUkH7G5qSnuIyQ=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "obuf": "^1.0.0",
+                "readable-stream": "^2.0.1",
+                "wbuf": "^1.1.0"
+            }
+        },
+        "node_modules/hpack.js/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/html": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz",
+            "integrity": "sha1-pUT6nqVJK/s6LMqCEKEL57WvH2E=",
+            "dependencies": {
+                "concat-stream": "^1.4.7"
+            },
+            "bin": {
+                "html": "bin/html.js"
+            }
+        },
+        "node_modules/html-encoding-sniffer": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+            "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+            "dev": true,
+            "dependencies": {
+                "whatwg-encoding": "^1.0.1"
+            }
+        },
+        "node_modules/html-entities": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz",
+            "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==",
+            "dev": true
+        },
+        "node_modules/html-to-image": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-0.1.1.tgz",
+            "integrity": "sha512-UAjpXmokENeOyzfLwL0+zQ502lXyg6pkzVUmRjtljOH9dR/YdEYQhWrQ/O14hmH5/1L7jv1aOupU4Zi3Y8+iow=="
+        },
+        "node_modules/html-to-text": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-5.1.1.tgz",
+            "integrity": "sha512-Bci6bD/JIfZSvG4s0gW/9mMKwBRoe/1RWLxUME/d6WUSZCdY7T60bssf/jFf7EYXRyqU4P5xdClVqiYU0/ypdA==",
+            "dependencies": {
+                "he": "^1.2.0",
+                "htmlparser2": "^3.10.1",
+                "lodash": "^4.17.11",
+                "minimist": "^1.2.0"
+            },
+            "bin": {
+                "html-to-text": "bin/cli.js"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/htmlparser2": {
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+            "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+            "dependencies": {
+                "domelementtype": "^1.3.1",
+                "domhandler": "^2.3.0",
+                "domutils": "^1.5.1",
+                "entities": "^1.1.1",
+                "inherits": "^2.0.1",
+                "readable-stream": "^3.1.1"
+            }
+        },
+        "node_modules/http-deceiver": {
+            "version": "1.2.7",
+            "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+            "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+            "dev": true
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "depd": "~1.1.2",
+                "inherits": "2.0.3",
+                "setprototypeof": "1.1.1",
+                "statuses": ">= 1.5.0 < 2",
+                "toidentifier": "1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/http-errors/node_modules/inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+        },
+        "node_modules/http-proxy": {
+            "version": "1.18.1",
+            "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+            "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+            "dev": true,
+            "dependencies": {
+                "eventemitter3": "^4.0.0",
+                "follow-redirects": "^1.0.0",
+                "requires-port": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "http-proxy": "^1.17.0",
+                "is-glob": "^4.0.0",
+                "lodash": "^4.17.11",
+                "micromatch": "^3.1.10"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/http-signature": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+            "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+            "dependencies": {
+                "assert-plus": "^1.0.0",
+                "jsprim": "^1.2.2",
+                "sshpk": "^1.7.0"
+            },
+            "engines": {
+                "node": ">=0.8",
+                "npm": ">=1.3.7"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/https-proxy-agent": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
+            "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
+            "dependencies": {
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/https-proxy-agent/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/hyphenate-style-name": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz",
+            "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ=="
+        },
+        "node_modules/i": {
+            "version": "0.3.6",
+            "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz",
+            "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=",
+            "engines": {
+                "node": ">=0.4"
+            }
+        },
+        "node_modules/iconv-lite": {
+            "version": "0.4.24",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+            "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/icss-replace-symbols": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+            "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+            "dev": true
+        },
+        "node_modules/icss-utils": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
+            "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
+            "dev": true,
+            "dependencies": {
+                "postcss": "^7.0.14"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/ieee754": {
+            "version": "1.1.13",
+            "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+            "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+        },
+        "node_modules/iferr": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+            "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+            "dev": true
+        },
+        "node_modules/ignore": {
+            "version": "3.3.10",
+            "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+            "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+            "dev": true
+        },
+        "node_modules/ignore-by-default": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+            "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk="
+        },
+        "node_modules/ignore-walk": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
+            "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
+            "dependencies": {
+                "minimatch": "^3.0.4"
+            }
+        },
+        "node_modules/image-data-uri": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/image-data-uri/-/image-data-uri-2.0.1.tgz",
+            "integrity": "sha512-BZh721F2Q5TwBdwpiqrBrHEdj8daj8KuMZK/DOCyqQlz1CqFhhuZWbK5ZCUnAvFJr8LaKHTaWl9ja3/a3DC2Ew==",
+            "dependencies": {
+                "fs-extra": "^0.26.7",
+                "magicli": "0.0.8",
+                "mime-types": "^2.1.18",
+                "request": "^2.88.0"
+            },
+            "bin": {
+                "image-data-uri": "bin/magicli.js"
+            }
+        },
+        "node_modules/image-size": {
+            "version": "0.7.5",
+            "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz",
+            "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==",
+            "bin": {
+                "image-size": "bin/image-size.js"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/image-size-stream": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/image-size-stream/-/image-size-stream-1.1.0.tgz",
+            "integrity": "sha1-Ivou2mbG31AQh0bacUkmSy0l+Gs=",
+            "dependencies": {
+                "image-size": "github:netroy/image-size#da2c863807a3e9602617bdd357b0de3ab4a064c1",
+                "readable-stream": "^1.0.33",
+                "tryit": "^1.0.1"
+            }
+        },
+        "node_modules/image-size-stream/node_modules/image-size": {
+            "resolved": "git+ssh://git@github.com/netroy/image-size.git#da2c863807a3e9602617bdd357b0de3ab4a064c1",
+            "bin": {
+                "image-size": "bin/image-size"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/image-size-stream/node_modules/isarray": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+            "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+        },
+        "node_modules/image-size-stream/node_modules/readable-stream": {
+            "version": "1.1.14",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+            "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.1",
+                "isarray": "0.0.1",
+                "string_decoder": "~0.10.x"
+            }
+        },
+        "node_modules/image-size-stream/node_modules/string_decoder": {
+            "version": "0.10.31",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+            "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+        },
+        "node_modules/immediate": {
+            "version": "3.0.6",
+            "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+            "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
+        },
+        "node_modules/import-fresh": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
+            "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
+            "dependencies": {
+                "parent-module": "^1.0.0",
+                "resolve-from": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/import-lazy": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+            "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "pkg-dir": "^3.0.0",
+                "resolve-cwd": "^2.0.0"
+            },
+            "bin": {
+                "import-local-fixture": "fixtures/cli.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/import-local/node_modules/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,
+            "dependencies": {
+                "find-up": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/imurmurhash": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+            "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+            "engines": {
+                "node": ">=0.8.19"
+            }
+        },
+        "node_modules/in-publish": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
+            "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==",
+            "bin": {
+                "in-install": "in-install.js",
+                "in-publish": "in-publish.js",
+                "not-in-install": "not-in-install.js",
+                "not-in-publish": "not-in-publish.js"
+            }
+        },
+        "node_modules/indent-string": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+            "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+            "dependencies": {
+                "repeating": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/indexes-of": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+            "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+            "dev": true
+        },
+        "node_modules/indexof": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+            "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+        },
+        "node_modules/infer-owner": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+            "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+            "dev": true
+        },
+        "node_modules/inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/infobox-parser": {
+            "version": "3.3.1",
+            "resolved": "https://registry.npmjs.org/infobox-parser/-/infobox-parser-3.3.1.tgz",
+            "integrity": "sha512-Aj1uF/taawGhet8cazhXz2uEDFMOqH8hnuw720wvi7Zw6bJWmA45Ta2FI9xMG5wvvo4CB6GR9S1/RUFtC6EtAg==",
+            "dependencies": {
+                "camelcase": "^4.1.0"
+            }
+        },
+        "node_modules/infobox-parser/node_modules/camelcase": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+            "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+        },
+        "node_modules/ini": {
+            "version": "1.3.5",
+            "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+            "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/inline-style-prefixer": {
+            "version": "3.0.8",
+            "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz",
+            "integrity": "sha1-hVG45bTVcyROZqNLBPfTIHaitTQ=",
+            "dependencies": {
+                "bowser": "^1.7.3",
+                "css-in-js-utils": "^2.0.0"
+            }
+        },
+        "node_modules/inspect-function": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
+            "integrity": "sha1-hdoMUli8TDMK4yg7Z0fgdZ2QpjU=",
+            "dependencies": {
+                "split-skip": "0.0.1",
+                "unpack-string": "0.0.2"
+            }
+        },
+        "node_modules/inspect-function/node_modules/split-skip": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz",
+            "integrity": "sha1-gK2ONumOV2RUzDtmfB3SXYZejwA="
+        },
+        "node_modules/inspect-parameters-declaration": {
+            "version": "0.0.9",
+            "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.9.tgz",
+            "integrity": "sha512-c3jrKKA1rwwrsjdGMAo2hFWV0vNe3/RKHxpE/OBt41LP3ynOVI1qmgxpZYK5SQu3jtWCyaho8L7AZzCjJ4mEUw==",
+            "dependencies": {
+                "magicli": "0.0.5",
+                "split-skip": "0.0.2",
+                "stringify-parameters": "0.0.4",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "inspect-parameters-declaration": "bin/cli.js"
+            }
+        },
+        "node_modules/inspect-parameters-declaration/node_modules/magicli": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
+            "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
+            "dependencies": {
+                "commander": "^2.9.0",
+                "get-stdin": "^5.0.1",
+                "inspect-function": "^0.2.1",
+                "pipe-functions": "^1.2.0"
+            }
+        },
+        "node_modules/inspect-property": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/inspect-property/-/inspect-property-0.0.6.tgz",
+            "integrity": "sha512-LgjHkRl9W6bj2n+kWrAOgvCYPTYt+LanE4rtd/vKNq6yEb+SvVV7UTLzoSPpDX6/U1cAz7VfqPr+lPAIz7wHaQ==",
+            "dependencies": {
+                "for-each-property": "0.0.4",
+                "for-each-property-deep": "0.0.3",
+                "inspect-function": "^0.3.1"
+            }
+        },
+        "node_modules/inspect-property/node_modules/inspect-function": {
+            "version": "0.3.4",
+            "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.3.4.tgz",
+            "integrity": "sha512-s0RsbJqK/sNZ+U1mykGoTickog3ea1A9Qk4mXniogOBu4PgkkZ56elScO7QC/r8D94lhGmJ2NyDI1ipOA/uq/g==",
+            "dependencies": {
+                "inspect-parameters-declaration": "0.0.8",
+                "magicli": "0.0.8",
+                "split-skip": "0.0.1",
+                "stringify-parameters": "0.0.4",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "inspect-function": "bin/magicli.js"
+            }
+        },
+        "node_modules/inspect-property/node_modules/inspect-parameters-declaration": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.8.tgz",
+            "integrity": "sha512-W4QzN1LgFmasKOM+NoLlDd2OAZM3enNZlVUOXoGQKmYBDFgxoPDOyebF55ALaf8avyM9TavNwibXxg347RrzCg==",
+            "dependencies": {
+                "magicli": "0.0.5",
+                "split-skip": "0.0.2",
+                "stringify-parameters": "0.0.4",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "inspect-parameters-declaration": "bin/cli.js"
+            }
+        },
+        "node_modules/inspect-property/node_modules/inspect-parameters-declaration/node_modules/inspect-function": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
+            "integrity": "sha1-hdoMUli8TDMK4yg7Z0fgdZ2QpjU=",
+            "dependencies": {
+                "split-skip": "0.0.1",
+                "unpack-string": "0.0.2"
+            }
+        },
+        "node_modules/inspect-property/node_modules/inspect-parameters-declaration/node_modules/inspect-function/node_modules/split-skip": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz",
+            "integrity": "sha1-gK2ONumOV2RUzDtmfB3SXYZejwA="
+        },
+        "node_modules/inspect-property/node_modules/inspect-parameters-declaration/node_modules/magicli": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
+            "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
+            "dependencies": {
+                "commander": "^2.9.0",
+                "get-stdin": "^5.0.1",
+                "inspect-function": "^0.2.1",
+                "pipe-functions": "^1.2.0"
+            }
+        },
+        "node_modules/inspect-property/node_modules/inspect-parameters-declaration/node_modules/split-skip": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.2.tgz",
+            "integrity": "sha1-2J2Iu9L3Pka1FYqjcKVhIk6A1GE="
+        },
+        "node_modules/inspect-property/node_modules/split-skip": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.1.tgz",
+            "integrity": "sha1-gK2ONumOV2RUzDtmfB3SXYZejwA="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "default-gateway": "^4.2.0",
+                "ipaddr.js": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/internmap": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.0.tgz",
+            "integrity": "sha512-SdoDWwNOTE2n4JWUsLn4KXZGuZPjPF9yyOGc8bnfWnBQh7BD/l80rzSznKc/r4Y0aQ7z3RTk9X+tV4tHBpu+dA=="
+        },
+        "node_modules/interpret": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
+            "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/interval-arithmetic": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/interval-arithmetic/-/interval-arithmetic-1.0.6.tgz",
+            "integrity": "sha512-eVotDGYPNiEaJ63oa4CeEHgOczZJ3gNHqG5wfVQ2o8sN2CEczQyR82Sjey/Bp36x8e7PtBcBvitcMnw6VUpjgQ==",
+            "dependencies": {
+                "@types/assert": "^1.4.6",
+                "is-safe-integer": "^2.0.0",
+                "nextafter": "^1.0.0",
+                "typedarray": "0.0.6"
+            }
+        },
+        "node_modules/interval-arithmetic-eval": {
+            "version": "0.4.7",
+            "resolved": "https://registry.npmjs.org/interval-arithmetic-eval/-/interval-arithmetic-eval-0.4.7.tgz",
+            "integrity": "sha512-ClK+N4efbsgjlZR8h0qd0LQbyzUzJ9IkrjmTnD5MVb4Ytebd0lesoVP4AxLclcsEI+nIieskQ8cepHIWUPaRhQ==",
+            "dependencies": {
+                "interval-arithmetic": "^1.0.6",
+                "math-codegen": "^0.3.5"
+            }
+        },
+        "node_modules/ip": {
+            "version": "1.1.5",
+            "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+            "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+            "dev": true
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/ipaddr.js": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+            "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/is-absolute-url": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
+            "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "kind-of": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-accessor-descriptor/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/is-accessor-descriptor/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-arguments": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
+            "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/is-arrayish": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+            "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "binary-extensions": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-buffer": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+            "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/is-callable": {
+            "version": "1.1.5",
+            "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+            "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/is-ci": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+            "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+            "dependencies": {
+                "ci-info": "^1.5.0"
+            },
+            "bin": {
+                "is-ci": "bin.js"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "kind-of": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-data-descriptor/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/is-data-descriptor/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-date-object": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+            "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/is-descriptor": {
+            "version": "0.1.6",
+            "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+            "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+            "dependencies": {
+                "is-accessor-descriptor": "^0.1.6",
+                "is-data-descriptor": "^0.1.4",
+                "kind-of": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-descriptor/node_modules/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==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-directory": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+            "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-expression": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
+            "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
+            "dependencies": {
+                "acorn": "~4.0.2",
+                "object-assign": "^4.0.1"
+            }
+        },
+        "node_modules/is-expression/node_modules/acorn": {
+            "version": "4.0.13",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+            "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "is-plain-object": "^2.0.4"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-extglob": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+            "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-finite": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
+            "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "is-extglob": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-in-browser": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
+            "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
+        },
+        "node_modules/is-installed-globally": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+            "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+            "dependencies": {
+                "global-dirs": "^0.1.0",
+                "is-path-inside": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/is-npm": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+            "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-number": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+            "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+            "dependencies": {
+                "kind-of": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-number/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/is-number/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-obj": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+            "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-path-cwd": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+            "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "is-path-inside": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/is-path-in-cwd/node_modules/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,
+            "dependencies": {
+                "path-is-inside": "^1.0.2"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "path-is-inside": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "isobject": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-promise": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+            "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
+        },
+        "node_modules/is-redirect": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+            "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-regex": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+            "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+            "dependencies": {
+                "has": "^1.0.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/is-retry-allowed": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+            "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-safe-integer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/is-safe-integer/-/is-safe-integer-2.0.0.tgz",
+            "integrity": "sha512-eDaA39/1+3SNtYTRP28lRYOHMwiB1gfqXQaXcf/+f4mLwKgm8TTDkwJldsdtbgrK1R5CoDbf6AQ0KqP7BKoGtQ==",
+            "dependencies": {
+                "max-safe-integer": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-stream": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+            "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-symbol": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+            "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+            "dependencies": {
+                "has-symbols": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/is-typedarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+            "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+        },
+        "node_modules/is-utf8": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+            "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+        },
+        "node_modules/is-what": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.10.0.tgz",
+            "integrity": "sha512-U4RYCXNOmATQHlOPlOCHCfXyKEFIPqvyaKDqYRuLbD6EYKcTTfc3YXkAYjzOVxO3zt34L+Wh2feIyWrYiZ7kng=="
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-wsl": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+            "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+        },
+        "node_modules/isexe": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+            "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+        },
+        "node_modules/isobject": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+            "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/isomorphic-fetch": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+            "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+            "dependencies": {
+                "node-fetch": "^1.0.1",
+                "whatwg-fetch": ">=0.10.0"
+            }
+        },
+        "node_modules/isstream": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+            "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+        },
+        "node_modules/its-set": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/its-set/-/its-set-1.2.3.tgz",
+            "integrity": "sha512-UQc+xLLn+0a8KKRXRj3OS2kERK8G7zcayPpPULqZnPwuJ1hGWEO8+j0T5eycu7DKXYjezw3pyF8oV1fJkJxV5w==",
+            "dependencies": {
+                "babel-runtime": "6.x.x",
+                "lodash.get": "^4.4.2"
+            }
+        },
+        "node_modules/jquery": {
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
+            "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg=="
+        },
+        "node_modules/js-base64": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.2.tgz",
+            "integrity": "sha512-Vg8czh0Q7sFBSUMWWArX/miJeBWYBPpdU/3M/DKSaekLMqrqVPaedp+5mZhie/r0lgrcaYBfwXatEew6gwgiQQ=="
+        },
+        "node_modules/js-datepicker": {
+            "version": "4.6.6",
+            "resolved": "https://registry.npmjs.org/js-datepicker/-/js-datepicker-4.6.6.tgz",
+            "integrity": "sha512-kLsE2oHfQM6pzdWNA7Y8HwCHaZIVURItPds7YVJnbe1z1OmQFzN7lfg6yFbDDWOyNjdHZGzWDy3jSDN2W0pNZQ=="
+        },
+        "node_modules/js-stringify": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
+            "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
+        },
+        "node_modules/js-tokens": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+            "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+        },
+        "node_modules/js-yaml": {
+            "version": "3.13.1",
+            "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+            "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+            "dependencies": {
+                "argparse": "^1.0.7",
+                "esprima": "^4.0.0"
+            },
+            "bin": {
+                "js-yaml": "bin/js-yaml.js"
+            }
+        },
+        "node_modules/jsbn": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+            "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+        },
+        "node_modules/jsdom": {
+            "version": "15.2.1",
+            "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+            "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+            "dev": true,
+            "dependencies": {
+                "abab": "^2.0.0",
+                "acorn": "^7.1.0",
+                "acorn-globals": "^4.3.2",
+                "array-equal": "^1.0.0",
+                "cssom": "^0.4.1",
+                "cssstyle": "^2.0.0",
+                "data-urls": "^1.1.0",
+                "domexception": "^1.0.1",
+                "escodegen": "^1.11.1",
+                "html-encoding-sniffer": "^1.0.2",
+                "nwsapi": "^2.2.0",
+                "parse5": "5.1.0",
+                "pn": "^1.1.0",
+                "request": "^2.88.0",
+                "request-promise-native": "^1.0.7",
+                "saxes": "^3.1.9",
+                "symbol-tree": "^3.2.2",
+                "tough-cookie": "^3.0.1",
+                "w3c-hr-time": "^1.0.1",
+                "w3c-xmlserializer": "^1.1.2",
+                "webidl-conversions": "^4.0.2",
+                "whatwg-encoding": "^1.0.5",
+                "whatwg-mimetype": "^2.3.0",
+                "whatwg-url": "^7.0.0",
+                "ws": "^7.0.0",
+                "xml-name-validator": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/jsdom/node_modules/acorn": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
+            "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
+            "dev": true,
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/jsdom/node_modules/acorn-globals": {
+            "version": "4.3.4",
+            "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+            "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+            "dev": true,
+            "dependencies": {
+                "acorn": "^6.0.1",
+                "acorn-walk": "^6.0.1"
+            }
+        },
+        "node_modules/jsdom/node_modules/acorn-globals/node_modules/acorn": {
+            "version": "6.4.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
+            "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
+            "dev": true,
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/jsdom/node_modules/parse5": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+            "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+            "dev": true
+        },
+        "node_modules/jsdom/node_modules/tough-cookie": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+            "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+            "dev": true,
+            "dependencies": {
+                "ip-regex": "^2.1.0",
+                "psl": "^1.1.28",
+                "punycode": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/jsesc": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+            "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+            "bin": {
+                "jsesc": "bin/jsesc"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/json-bigint": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
+            "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
+            "dependencies": {
+                "bignumber.js": "^7.0.0"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/json-schema": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+            "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+        },
+        "node_modules/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=="
+        },
+        "node_modules/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="
+        },
+        "node_modules/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
+        },
+        "node_modules/jsondiffpatch": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/jsondiffpatch/-/jsondiffpatch-0.4.1.tgz",
+            "integrity": "sha512-t0etAxTUk1w5MYdNOkZBZ8rvYYN5iL+2dHCCx/DpkFm/bW28M6y5nUS83D4XdZiHy35Fpaw6LBb+F88fHZnVCw==",
+            "dependencies": {
+                "chalk": "^2.3.0",
+                "diff-match-patch": "^1.0.0"
+            },
+            "bin": {
+                "jsondiffpatch": "bin/jsondiffpatch"
+            },
+            "engines": {
+                "node": ">=8.17.0"
+            }
+        },
+        "node_modules/jsonfile": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+            "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+            "dependencies": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "node_modules/jsonschema": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.6.tgz",
+            "integrity": "sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/jsprim": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+            "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+            "engines": [
+                "node >=0.6.0"
+            ],
+            "dependencies": {
+                "assert-plus": "1.0.0",
+                "extsprintf": "1.3.0",
+                "json-schema": "0.2.3",
+                "verror": "1.10.0"
+            }
+        },
+        "node_modules/jss": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss/-/jss-10.3.0.tgz",
+            "integrity": "sha512-B5sTRW9B6uHaUVzSo9YiMEOEp3UX8lWevU0Fsv+xtRnsShmgCfIYX44bTH8bPJe6LQKqEXku3ulKuHLbxBS97Q==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "csstype": "^2.6.5",
+                "is-in-browser": "^1.1.3",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "node_modules/jss-plugin-camel-case": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.3.0.tgz",
+            "integrity": "sha512-tadWRi/SLWqLK3EUZEdDNJL71F3ST93Zrl9JYMjV0QDqKPAl0Liue81q7m/nFUpnSTXczbKDy4wq8rI8o7WFqA==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "hyphenate-style-name": "^1.0.3",
+                "jss": "^10.3.0"
+            }
+        },
+        "node_modules/jss-plugin-default-unit": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.3.0.tgz",
+            "integrity": "sha512-tT5KkIXAsZOSS9WDSe8m8lEHIjoEOj4Pr0WrG0WZZsMXZ1mVLFCSsD2jdWarQWDaRNyMj/I4d7czRRObhOxSuw==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "node_modules/jss-plugin-global": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.3.0.tgz",
+            "integrity": "sha512-etYTG/y3qIR/vxZnKY+J3wXwObyBDNhBiB3l/EW9/pE3WHE//BZdK8LFvQcrCO48sZW1Z6paHo6klxUPP7WbzA==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "node_modules/jss-plugin-nested": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.3.0.tgz",
+            "integrity": "sha512-qWiEkoXNEkkZ+FZrWmUGpf+zBsnEOmKXhkjNX85/ZfWhH9dfGxUCKuJFuOWFM+rjQfxV4csfesq4hY0jk8Qt0w==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "node_modules/jss-plugin-props-sort": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.3.0.tgz",
+            "integrity": "sha512-boetORqL/lfd7BWeFD3K+IyPqyIC+l3CRrdZr+NPq7Noqp+xyg/0MR7QisgzpxCEulk+j2CRcEUoZsvgPC4nTg==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0"
+            }
+        },
+        "node_modules/jss-plugin-rule-value-function": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.3.0.tgz",
+            "integrity": "sha512-7WiMrKIHH3rwxTuJki9+7nY11r1UXqaUZRhHvqTD4/ZE+SVhvtD5Tx21ivNxotwUSleucA/8boX+NF21oXzr5Q==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "jss": "^10.3.0",
+                "tiny-warning": "^1.0.2"
+            }
+        },
+        "node_modules/jss-plugin-vendor-prefixer": {
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.3.0.tgz",
+            "integrity": "sha512-sZQbrcZyP5V0ADjCLwUA1spVWoaZvM7XZ+2fSeieZFBj31cRsnV7X70FFDerMHeiHAXKWzYek+67nMDjhrZAVQ==",
+            "dependencies": {
+                "@babel/runtime": "^7.3.1",
+                "css-vendor": "^2.0.8",
+                "jss": "^10.3.0"
+            }
+        },
+        "node_modules/jstransformer": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
+            "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
+            "dependencies": {
+                "is-promise": "^2.0.0",
+                "promise": "^7.0.1"
+            }
+        },
+        "node_modules/jszip": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.5.0.tgz",
+            "integrity": "sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA==",
+            "dependencies": {
+                "lie": "~3.3.0",
+                "pako": "~1.0.2",
+                "readable-stream": "~2.3.6",
+                "set-immediate-shim": "~1.0.1"
+            }
+        },
+        "node_modules/jszip/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/jwa": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+            "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+            "dependencies": {
+                "buffer-equal-constant-time": "1.0.1",
+                "ecdsa-sig-formatter": "1.0.11",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/jws": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+            "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+            "dependencies": {
+                "jwa": "^1.4.1",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/kareem": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
+            "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
+        },
+        "node_modules/keycode": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+            "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+        },
+        "node_modules/keygrip": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
+            "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
+            "dependencies": {
+                "tsscmp": "1.0.6"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/killable": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+            "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+            "dev": true
+        },
+        "node_modules/kind-of": {
+            "version": "6.0.3",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+            "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/klaw": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+            "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+            "dependencies": {
+                "graceful-fs": "^4.1.9"
+            }
+        },
+        "node_modules/latest-version": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+            "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+            "dependencies": {
+                "package-json": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/lazy-cache": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+            "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/lazystream": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+            "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+            "dependencies": {
+                "readable-stream": "^2.0.5"
+            },
+            "engines": {
+                "node": ">= 0.6.3"
+            }
+        },
+        "node_modules/lazystream/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/levn": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+            "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "~1.1.2",
+                "type-check": "~0.3.2"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/libxmljs": {
+            "version": "0.19.7",
+            "resolved": "https://registry.npmjs.org/libxmljs/-/libxmljs-0.19.7.tgz",
+            "integrity": "sha512-lFJyG9T1mVwTzNTw6ZkvIt0O+NsIR+FTE+RcC2QDFGU8YMnQrnyEOGrj6HWSe1AdwQK7s37BOp4NL+pcAqfK2g==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "bindings": "~1.3.0",
+                "nan": "~2.14.0",
+                "node-pre-gyp": "~0.11.0"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/libxmljs/node_modules/node-pre-gyp": {
+            "version": "0.11.0",
+            "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
+            "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
+            "dependencies": {
+                "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"
+            },
+            "bin": {
+                "node-pre-gyp": "bin/node-pre-gyp"
+            }
+        },
+        "node_modules/libxmljs/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/lie": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+            "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+            "dependencies": {
+                "immediate": "~3.0.5"
+            }
+        },
+        "node_modules/lines-and-columns": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+            "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA="
+        },
+        "node_modules/load-json-file": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+            "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "parse-json": "^2.2.0",
+                "pify": "^2.0.0",
+                "pinkie-promise": "^2.0.0",
+                "strip-bom": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/load-json-file/node_modules/parse-json": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+            "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+            "dependencies": {
+                "error-ex": "^1.2.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/load-json-file/node_modules/pify": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+            "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=4.3.0 <5.0.0 || >=5.10"
+            }
+        },
+        "node_modules/loader-utils": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+            "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+            "dependencies": {
+                "big.js": "^5.2.2",
+                "emojis-list": "^3.0.0",
+                "json5": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/loader-utils/node_modules/json5": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+            "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+            "dependencies": {
+                "minimist": "^1.2.0"
+            },
+            "bin": {
+                "json5": "lib/cli.js"
+            }
+        },
+        "node_modules/locate-path": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+            "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+            "dependencies": {
+                "p-locate": "^3.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/lodash": {
+            "version": "4.17.15",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+            "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+        },
+        "node_modules/lodash._getnative": {
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
+            "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
+        },
+        "node_modules/lodash.chunk": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
+            "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw="
+        },
+        "node_modules/lodash.curry": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
+            "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA="
+        },
+        "node_modules/lodash.debounce": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz",
+            "integrity": "sha1-gSIRw3ipTMKdWqTjNGzwv846ffU=",
+            "dependencies": {
+                "lodash._getnative": "^3.0.0"
+            }
+        },
+        "node_modules/lodash.defaults": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+            "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
+        },
+        "node_modules/lodash.difference": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
+            "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
+        },
+        "node_modules/lodash.flatten": {
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
+            "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
+        },
+        "node_modules/lodash.flow": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
+            "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o="
+        },
+        "node_modules/lodash.get": {
+            "version": "4.4.2",
+            "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+            "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+        },
+        "node_modules/lodash.isequal": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+            "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
+        },
+        "node_modules/lodash.isplainobject": {
+            "version": "4.0.6",
+            "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+            "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
+        },
+        "node_modules/lodash.memoize": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+            "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
+        },
+        "node_modules/lodash.merge": {
+            "version": "4.6.2",
+            "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+            "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
+        },
+        "node_modules/lodash.padend": {
+            "version": "4.6.1",
+            "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
+            "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4="
+        },
+        "node_modules/lodash.sortby": {
+            "version": "4.7.0",
+            "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+            "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+            "dev": true
+        },
+        "node_modules/lodash.throttle": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+            "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+        },
+        "node_modules/lodash.union": {
+            "version": "4.6.0",
+            "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
+            "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
+        },
+        "node_modules/log-symbols": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+            "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+            "dependencies": {
+                "chalk": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/loglevel": {
+            "version": "1.6.8",
+            "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz",
+            "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.6.0"
+            }
+        },
+        "node_modules/loglevelnext": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz",
+            "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==",
+            "dev": true,
+            "dependencies": {
+                "es6-symbol": "^3.1.1",
+                "object.assign": "^4.1.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/longest": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+            "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "js-tokens": "^3.0.0 || ^4.0.0"
+            },
+            "bin": {
+                "loose-envify": "cli.js"
+            }
+        },
+        "node_modules/loud-rejection": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+            "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+            "dependencies": {
+                "currently-unhandled": "^0.4.1",
+                "signal-exit": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/lowercase-keys": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+            "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "yallist": "^3.0.2"
+            }
+        },
+        "node_modules/magicli": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.8.tgz",
+            "integrity": "sha512-x/eBenweAHF+DsYy172sK4doRxZl0yrJnfxhLJiN7H6hPM3Ya0PfI6uBZshZ3ScFFSQD7HXgBqMdbnXKEZsO1g==",
+            "dependencies": {
+                "cliss": "0.0.2",
+                "find-up": "^2.1.0",
+                "for-each-property": "0.0.4",
+                "inspect-property": "0.0.6"
+            }
+        },
+        "node_modules/magicli/node_modules/find-up": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+            "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+            "dependencies": {
+                "locate-path": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/magicli/node_modules/locate-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+            "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+            "dependencies": {
+                "p-locate": "^2.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/magicli/node_modules/p-limit": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+            "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+            "dependencies": {
+                "p-try": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/magicli/node_modules/p-locate": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+            "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+            "dependencies": {
+                "p-limit": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/magicli/node_modules/p-try": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+            "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/make-dir": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+            "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+            "dependencies": {
+                "pify": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/make-dir/node_modules/pify": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+            "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/make-error": {
+            "version": "1.3.6",
+            "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+            "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+            "dev": true
+        },
+        "node_modules/map-cache": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+            "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/map-obj": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+            "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/map-visit": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+            "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+            "dependencies": {
+                "object-visit": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/material-colors": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz",
+            "integrity": "sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg=="
+        },
+        "node_modules/material-ui": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/material-ui/-/material-ui-0.20.2.tgz",
+            "integrity": "sha512-VeqgQkdvtK193w+FFvXDEwlVxI4rWk83eWbpYLeOIHDPWr3rbB9B075JRnJt/8IsI2X8q5Aia5W3+7m4KkleDg==",
+            "dependencies": {
+                "babel-runtime": "^6.23.0",
+                "inline-style-prefixer": "^3.0.8",
+                "keycode": "^2.1.8",
+                "lodash.merge": "^4.6.0",
+                "lodash.throttle": "^4.1.1",
+                "prop-types": "^15.5.7",
+                "react-event-listener": "^0.6.2",
+                "react-transition-group": "^1.2.1",
+                "recompose": "^0.26.0",
+                "simple-assign": "^0.1.0",
+                "warning": "^3.0.0"
+            }
+        },
+        "node_modules/material-ui/node_modules/react-transition-group": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz",
+            "integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==",
+            "dependencies": {
+                "chain-function": "^1.0.0",
+                "dom-helpers": "^3.2.0",
+                "loose-envify": "^1.3.1",
+                "prop-types": "^15.5.6",
+                "warning": "^3.0.0"
+            }
+        },
+        "node_modules/math-codegen": {
+            "version": "0.3.5",
+            "resolved": "https://registry.npmjs.org/math-codegen/-/math-codegen-0.3.5.tgz",
+            "integrity": "sha1-R5nuRnfe0Ud2bQA8ykt4ee3UDMo=",
+            "dependencies": {
+                "extend": "^3.0.0",
+                "mr-parser": "^0.2.1"
+            }
+        },
+        "node_modules/mathquill": {
+            "version": "0.10.1-a",
+            "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1-a.tgz",
+            "integrity": "sha1-vyylaQEAY6w0vNXVKa3Ag3zVPD8=",
+            "dependencies": {
+                "jquery": "^1.12.3"
+            }
+        },
+        "node_modules/mathquill/node_modules/jquery": {
+            "version": "1.12.4",
+            "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz",
+            "integrity": "sha1-AeHfuikP5z3rp3zurLD5ui/sngw="
+        },
+        "node_modules/max-safe-integer": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/max-safe-integer/-/max-safe-integer-1.0.1.tgz",
+            "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "hash-base": "^3.0.0",
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.1.2"
+            }
+        },
+        "node_modules/media-typer": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/memoize-one": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz",
+            "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA=="
+        },
+        "node_modules/memory-fs": {
+            "version": "0.5.0",
+            "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+            "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+            "dev": true,
+            "dependencies": {
+                "errno": "^0.1.3",
+                "readable-stream": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=4.3.0 <5.0.0 || >=5.10"
+            }
+        },
+        "node_modules/memory-fs/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/memory-pager": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
+            "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
+            "optional": true
+        },
+        "node_modules/meow": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+            "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+            "dependencies": {
+                "camelcase-keys": "^2.0.0",
+                "decamelize": "^1.1.2",
+                "loud-rejection": "^1.0.0",
+                "map-obj": "^1.0.1",
+                "minimist": "^1.1.3",
+                "normalize-package-data": "^2.3.4",
+                "object-assign": "^4.0.1",
+                "read-pkg-up": "^1.0.1",
+                "redent": "^1.0.0",
+                "trim-newlines": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/merge-anything": {
+            "version": "2.4.4",
+            "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz",
+            "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==",
+            "dependencies": {
+                "is-what": "^3.3.1"
+            }
+        },
+        "node_modules/merge-descriptors": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+            "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+        },
+        "node_modules/methods": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+            "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/microevent.ts": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz",
+            "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==",
+            "dev": true
+        },
+        "node_modules/micromatch": {
+            "version": "3.1.10",
+            "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+            "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "bn.js": "^4.0.0",
+                "brorand": "^1.0.1"
+            },
+            "bin": {
+                "miller-rabin": "bin/miller-rabin"
+            }
+        },
+        "node_modules/miller-rabin/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/mime": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+            "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/mime-db": {
+            "version": "1.44.0",
+            "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
+            "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mime-types": {
+            "version": "2.1.27",
+            "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
+            "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
+            "dependencies": {
+                "mime-db": "1.44.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/mimic-response": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+            "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/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
+        },
+        "node_modules/minimatch": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+            "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/minimist": {
+            "version": "1.2.5",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+            "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+        },
+        "node_modules/minipass": {
+            "version": "2.9.0",
+            "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+            "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/minizlib": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+            "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+            "dependencies": {
+                "minipass": "^2.9.0"
+            }
+        },
+        "node_modules/mississippi": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
+            "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
+            "dev": true,
+            "dependencies": {
+                "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": "^2.0.1",
+                "pumpify": "^1.3.3",
+                "stream-each": "^1.1.0",
+                "through2": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/mississippi/node_modules/pump": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+            "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+            "dev": true,
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/mixin-deep": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+            "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+            "dependencies": {
+                "for-in": "^1.0.2",
+                "is-extendable": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/mkdirp": {
+            "version": "0.5.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
+            "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
+            "dependencies": {
+                "minimist": "^1.2.5"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/mkdirp-classic": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.2.tgz",
+            "integrity": "sha512-ejdnDQcR75gwknmMw/tx02AuRs8jCtqFoFqDZMjiNxsu85sRIJVXDKHuLYvUUPRBUtV2FpSZa9bL1BUa3BdR2g=="
+        },
+        "node_modules/mobile-detect": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.4.tgz",
+            "integrity": "sha512-vTgEjKjS89C5yHL5qWPpT6BzKuOVqABp+A3Szpbx34pIy3sngxlGaFpgHhfj6fKze1w0QKeOSDbU7SKu7wDvRQ=="
+        },
+        "node_modules/mobx": {
+            "version": "5.15.7",
+            "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.7.tgz",
+            "integrity": "sha512-wyM3FghTkhmC+hQjyPGGFdpehrcX1KOXsDuERhfK2YbJemkUhEB+6wzEN639T21onxlfYBmriA1PFnvxTUhcKw=="
+        },
+        "node_modules/mobx-react": {
+            "version": "5.4.4",
+            "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz",
+            "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==",
+            "dependencies": {
+                "hoist-non-react-statics": "^3.0.0",
+                "react-lifecycles-compat": "^3.0.2"
+            }
+        },
+        "node_modules/mobx-react-devtools": {
+            "version": "6.1.1",
+            "resolved": "https://registry.npmjs.org/mobx-react-devtools/-/mobx-react-devtools-6.1.1.tgz",
+            "integrity": "sha512-nc5IXLdEUFLn3wZal65KF3/JFEFd+mbH4KTz/IG5BOPyw7jo8z29w/8qm7+wiCyqVfUIgJ1gL4+HVKmcXIOgqA=="
+        },
+        "node_modules/mobx-utils": {
+            "version": "5.6.1",
+            "resolved": "https://registry.npmjs.org/mobx-utils/-/mobx-utils-5.6.1.tgz",
+            "integrity": "sha512-bpTJzM8MXniGnXCZY+ImjPDqBKQ3+G3g/QFSPtNkH6HM3x14DAPqKH7No7NDyhbXBMv3FaVetsgnoEPozbi45Q=="
+        },
+        "node_modules/mocha": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+            "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+            "dev": true,
+            "dependencies": {
+                "browser-stdout": "1.3.1",
+                "commander": "2.15.1",
+                "debug": "3.1.0",
+                "diff": "3.5.0",
+                "escape-string-regexp": "1.0.5",
+                "glob": "7.1.2",
+                "growl": "1.10.5",
+                "he": "1.1.1",
+                "minimatch": "3.0.4",
+                "mkdirp": "0.5.1",
+                "supports-color": "5.4.0"
+            },
+            "bin": {
+                "_mocha": "bin/_mocha",
+                "mocha": "bin/mocha"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/mocha/node_modules/commander": {
+            "version": "2.15.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+            "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+            "dev": true
+        },
+        "node_modules/mocha/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/mocha/node_modules/glob": {
+            "version": "7.1.2",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+            "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/mocha/node_modules/he": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+            "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+            "dev": true,
+            "bin": {
+                "he": "bin/he"
+            }
+        },
+        "node_modules/mocha/node_modules/minimist": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+            "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+            "dev": true
+        },
+        "node_modules/mocha/node_modules/mkdirp": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+            "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+            "dev": true,
+            "dependencies": {
+                "minimist": "0.0.8"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/mocha/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+            "dev": true
+        },
+        "node_modules/mocha/node_modules/supports-color": {
+            "version": "5.4.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+            "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+            "dev": true,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/mongodb": {
+            "version": "3.5.9",
+            "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.9.tgz",
+            "integrity": "sha512-vXHBY1CsGYcEPoVWhwgxIBeWqP3dSu9RuRDsoLRPTITrcrgm1f0Ubu1xqF9ozMwv53agmEiZm0YGo+7WL3Nbug==",
+            "dependencies": {
+                "bl": "^2.2.0",
+                "bson": "^1.1.4",
+                "denque": "^1.4.1",
+                "require_optional": "^1.0.1",
+                "safe-buffer": "^5.1.2"
+            },
+            "engines": {
+                "node": ">=4"
+            },
+            "optionalDependencies": {
+                "saslprep": "^1.0.0"
+            }
+        },
+        "node_modules/mongodb-core": {
+            "version": "2.1.20",
+            "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz",
+            "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==",
+            "dependencies": {
+                "bson": "~1.0.4",
+                "require_optional": "~1.0.0"
+            }
+        },
+        "node_modules/mongodb/node_modules/bl": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
+            "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
+            "dependencies": {
+                "readable-stream": "^2.3.5",
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/mongodb/node_modules/bson": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
+            "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==",
+            "engines": {
+                "node": ">=0.6.19"
+            }
+        },
+        "node_modules/mongodb/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/mongoose": {
+            "version": "5.9.20",
+            "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.20.tgz",
+            "integrity": "sha512-vRP6Csu2obzSl3ed7kTQMrolBNgweiRJ/eBU1PSe/rJfjqWS1oqDE2D1ZPGxkVOsKXs7Gyd84GAXerj8IB2UWg==",
+            "dependencies": {
+                "bson": "^1.1.4",
+                "kareem": "2.3.1",
+                "mongodb": "3.5.9",
+                "mongoose-legacy-pluralize": "1.0.2",
+                "mpath": "0.7.0",
+                "mquery": "3.2.2",
+                "ms": "2.1.2",
+                "regexp-clone": "1.0.0",
+                "safe-buffer": "5.1.2",
+                "sift": "7.0.1",
+                "sliced": "1.0.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/mongoose-legacy-pluralize": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
+            "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
+        },
+        "node_modules/mongoose/node_modules/bson": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
+            "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q==",
+            "engines": {
+                "node": ">=0.6.19"
+            }
+        },
+        "node_modules/mongoose/node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+        },
+        "node_modules/move-concurrently": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+            "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/move-concurrently/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/mpath": {
+            "version": "0.7.0",
+            "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
+            "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg==",
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/mquery": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
+            "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
+            "dependencies": {
+                "bluebird": "3.5.1",
+                "debug": "3.1.0",
+                "regexp-clone": "^1.0.0",
+                "safe-buffer": "5.1.2",
+                "sliced": "1.0.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/mquery/node_modules/bluebird": {
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+            "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
+        },
+        "node_modules/mquery/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/mquery/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/mr-parser": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/mr-parser/-/mr-parser-0.2.1.tgz",
+            "integrity": "sha1-hhi5ukF+KOn0OaQcaVtVTq/u2Sc="
+        },
+        "node_modules/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=="
+        },
+        "node_modules/multicast-dns": {
+            "version": "6.2.3",
+            "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+            "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+            "dev": true,
+            "dependencies": {
+                "dns-packet": "^1.3.1",
+                "thunky": "^1.0.2"
+            },
+            "bin": {
+                "multicast-dns": "cli.js"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/nan": {
+            "version": "2.14.1",
+            "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+            "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
+        },
+        "node_modules/nanoid": {
+            "version": "3.1.10",
+            "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.10.tgz",
+            "integrity": "sha512-iZFMXKeXWkxzlfmMfM91gw7YhN2sdJtixY+eZh9V6QWJWTOiurhpKhBMgr82pfzgSqglQgqYSCowEYsz8D++6w==",
+            "bin": {
+                "nanoid": "bin/nanoid.cjs"
+            },
+            "engines": {
+                "node": "^10 || ^12 || >=13.7"
+            }
+        },
+        "node_modules/nanomatch": {
+            "version": "1.2.13",
+            "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+            "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/napi-build-utils": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+            "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+        },
+        "node_modules/native-or-bluebird": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz",
+            "integrity": "sha1-OcR7/Xgl0fuf+tMiEK4l2q3xAck="
+        },
+        "node_modules/needle": {
+            "version": "2.4.1",
+            "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.1.tgz",
+            "integrity": "sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==",
+            "dependencies": {
+                "debug": "^3.2.6",
+                "iconv-lite": "^0.4.4",
+                "sax": "^1.2.4"
+            },
+            "bin": {
+                "needle": "bin/needle"
+            },
+            "engines": {
+                "node": ">= 4.4.x"
+            }
+        },
+        "node_modules/negotiator": {
+            "version": "0.6.2",
+            "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+            "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/neo-async": {
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
+            "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
+            "dev": true
+        },
+        "node_modules/next-tick": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+            "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+        },
+        "node_modules/nextafter": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/nextafter/-/nextafter-1.0.0.tgz",
+            "integrity": "sha1-t9d7U1MQ4+CX5gJauwqQNHfsGjo=",
+            "dependencies": {
+                "double-bits": "^1.1.0"
+            }
+        },
+        "node_modules/nice-try": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+            "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+            "dev": true
+        },
+        "node_modules/node-abi": {
+            "version": "2.16.0",
+            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.16.0.tgz",
+            "integrity": "sha512-+sa0XNlWDA6T+bDLmkCUYn6W5k5W6BPRL6mqzSCs6H/xUgtl4D5x2fORKDzopKiU6wsyn/+wXlRXwXeSp+mtoA==",
+            "dependencies": {
+                "semver": "^5.4.1"
+            }
+        },
+        "node_modules/node-ensure": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
+            "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc="
+        },
+        "node_modules/node-environment-flags": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
+            "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==",
+            "dependencies": {
+                "object.getownpropertydescriptors": "^2.0.3",
+                "semver": "^5.7.0"
+            }
+        },
+        "node_modules/node-fetch": {
+            "version": "1.7.3",
+            "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+            "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+            "dependencies": {
+                "encoding": "^0.1.11",
+                "is-stream": "^1.0.1"
+            }
+        },
+        "node_modules/node-forge": {
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz",
+            "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==",
+            "engines": {
+                "node": ">= 4.5.0"
+            }
+        },
+        "node_modules/node-gyp": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+            "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+            "dependencies": {
+                "fstream": "^1.0.0",
+                "glob": "^7.0.3",
+                "graceful-fs": "^4.1.2",
+                "mkdirp": "^0.5.0",
+                "nopt": "2 || 3",
+                "npmlog": "0 || 1 || 2 || 3 || 4",
+                "osenv": "0",
+                "request": "^2.87.0",
+                "rimraf": "2",
+                "semver": "~5.3.0",
+                "tar": "^2.0.0",
+                "which": "1"
+            },
+            "bin": {
+                "node-gyp": "bin/node-gyp.js"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/node-gyp/node_modules/nopt": {
+            "version": "3.0.6",
+            "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+            "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+            "dependencies": {
+                "abbrev": "1"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            }
+        },
+        "node_modules/node-gyp/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/node-gyp/node_modules/semver": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+            "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/node-gyp/node_modules/tar": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+            "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+            "dependencies": {
+                "block-stream": "*",
+                "fstream": "^1.0.12",
+                "inherits": "2"
+            }
+        },
+        "node_modules/node-libs-browser": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+            "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+            "dev": true,
+            "dependencies": {
+                "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.1",
+                "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": "^1.0.1"
+            }
+        },
+        "node_modules/node-libs-browser/node_modules/buffer": {
+            "version": "4.9.2",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+            "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+            "dev": true,
+            "dependencies": {
+                "base64-js": "^1.0.2",
+                "ieee754": "^1.1.4",
+                "isarray": "^1.0.0"
+            }
+        },
+        "node_modules/node-libs-browser/node_modules/punycode": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+            "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+            "dev": true
+        },
+        "node_modules/node-libs-browser/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/node-notifier": {
+            "version": "5.4.3",
+            "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz",
+            "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==",
+            "dev": true,
+            "dependencies": {
+                "growly": "^1.3.0",
+                "is-wsl": "^1.1.0",
+                "semver": "^5.5.0",
+                "shellwords": "^0.1.1",
+                "which": "^1.3.0"
+            }
+        },
+        "node_modules/node-sass": {
+            "version": "4.14.1",
+            "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.1.tgz",
+            "integrity": "sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "async-foreach": "^0.1.3",
+                "chalk": "^1.1.1",
+                "cross-spawn": "^3.0.0",
+                "gaze": "^1.0.0",
+                "get-stdin": "^4.0.1",
+                "glob": "^7.0.3",
+                "in-publish": "^2.0.0",
+                "lodash": "^4.17.15",
+                "meow": "^3.7.0",
+                "mkdirp": "^0.5.1",
+                "nan": "^2.13.2",
+                "node-gyp": "^3.8.0",
+                "npmlog": "^4.0.0",
+                "request": "^2.88.0",
+                "sass-graph": "2.2.5",
+                "stdout-stream": "^1.4.0",
+                "true-case-path": "^1.0.2"
+            },
+            "bin": {
+                "node-sass": "bin/node-sass"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass-tilde-importer": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/node-sass-tilde-importer/-/node-sass-tilde-importer-1.0.2.tgz",
+            "integrity": "sha512-Swcmr38Y7uB78itQeBm3mThjxBy9/Ah/ykPIaURY/L6Nec9AyRoL/jJ7ECfMR+oZeCTVQNxVMu/aHU+TLRVbdg==",
+            "dependencies": {
+                "find-parent-dir": "^0.3.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/ansi-styles": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+            "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/chalk": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+            "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/get-stdin": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+            "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/strip-ansi": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+            "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/node-sass/node_modules/supports-color": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+            "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/node-stream-zip": {
+            "version": "1.11.2",
+            "resolved": "https://registry.npmjs.org/node-stream-zip/-/node-stream-zip-1.11.2.tgz",
+            "integrity": "sha512-cowCX+OyzS3tN2i4BMMFxCr/pE6cQlEMTbVCugmos0TNEJQNtcG04tR41CY8lumO1I7F5GFiLaU4WavomJthaA==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/nodemailer": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-5.1.1.tgz",
+            "integrity": "sha512-hKGCoeNdFL2W7S76J/Oucbw0/qRlfG815tENdhzcqTpSjKgAN91mFOqU2lQUflRRxFM7iZvCyaFcAR9noc/CqQ==",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/nodemon": {
+            "version": "1.19.4",
+            "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz",
+            "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "chokidar": "^2.1.8",
+                "debug": "^3.2.6",
+                "ignore-by-default": "^1.0.1",
+                "minimatch": "^3.0.4",
+                "pstree.remy": "^1.1.7",
+                "semver": "^5.7.1",
+                "supports-color": "^5.5.0",
+                "touch": "^3.1.0",
+                "undefsafe": "^2.0.2",
+                "update-notifier": "^2.5.0"
+            },
+            "bin": {
+                "nodemon": "bin/nodemon.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/noop-logger": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
+            "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
+        },
+        "node_modules/nopt": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+            "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+            "dependencies": {
+                "abbrev": "1",
+                "osenv": "^0.1.4"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "hosted-git-info": "^2.1.4",
+                "resolve": "^1.10.0",
+                "semver": "2 || 3 || 4 || 5",
+                "validate-npm-package-license": "^3.0.1"
+            }
+        },
+        "node_modules/normalize-path": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+            "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/normalize.css": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz",
+            "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
+        },
+        "node_modules/npm": {
+            "version": "6.14.5",
+            "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.5.tgz",
+            "integrity": "sha512-CDwa3FJd0XJpKDbWCST484H+mCNjF26dPrU+xnREW+upR0UODjMEfXPl3bxWuAwZIX6c2ASg1plLO7jP8ehWeA==",
+            "bundleDependencies": [
+                "JSONStream",
+                "abbrev",
+                "ansicolors",
+                "ansistyles",
+                "aproba",
+                "archy",
+                "bin-links",
+                "bluebird",
+                "byte-size",
+                "cacache",
+                "call-limit",
+                "chownr",
+                "ci-info",
+                "cli-columns",
+                "cli-table3",
+                "cmd-shim",
+                "columnify",
+                "config-chain",
+                "debuglog",
+                "detect-indent",
+                "detect-newline",
+                "dezalgo",
+                "editor",
+                "figgy-pudding",
+                "find-npm-prefix",
+                "fs-vacuum",
+                "fs-write-stream-atomic",
+                "gentle-fs",
+                "glob",
+                "graceful-fs",
+                "has-unicode",
+                "hosted-git-info",
+                "iferr",
+                "imurmurhash",
+                "infer-owner",
+                "inflight",
+                "inherits",
+                "ini",
+                "init-package-json",
+                "is-cidr",
+                "json-parse-better-errors",
+                "lazy-property",
+                "libcipm",
+                "libnpm",
+                "libnpmaccess",
+                "libnpmhook",
+                "libnpmorg",
+                "libnpmsearch",
+                "libnpmteam",
+                "libnpx",
+                "lock-verify",
+                "lockfile",
+                "lodash._baseindexof",
+                "lodash._baseuniq",
+                "lodash._bindcallback",
+                "lodash._cacheindexof",
+                "lodash._createcache",
+                "lodash._getnative",
+                "lodash.clonedeep",
+                "lodash.restparam",
+                "lodash.union",
+                "lodash.uniq",
+                "lodash.without",
+                "lru-cache",
+                "meant",
+                "mississippi",
+                "mkdirp",
+                "move-concurrently",
+                "node-gyp",
+                "nopt",
+                "normalize-package-data",
+                "npm-audit-report",
+                "npm-cache-filename",
+                "npm-install-checks",
+                "npm-lifecycle",
+                "npm-package-arg",
+                "npm-packlist",
+                "npm-pick-manifest",
+                "npm-profile",
+                "npm-registry-fetch",
+                "npm-user-validate",
+                "npmlog",
+                "once",
+                "opener",
+                "osenv",
+                "pacote",
+                "path-is-inside",
+                "promise-inflight",
+                "qrcode-terminal",
+                "query-string",
+                "qw",
+                "read",
+                "read-cmd-shim",
+                "read-installed",
+                "read-package-json",
+                "read-package-tree",
+                "readable-stream",
+                "readdir-scoped-modules",
+                "request",
+                "retry",
+                "rimraf",
+                "safe-buffer",
+                "semver",
+                "sha",
+                "slide",
+                "sorted-object",
+                "sorted-union-stream",
+                "ssri",
+                "stringify-package",
+                "tar",
+                "text-table",
+                "tiny-relative-date",
+                "uid-number",
+                "umask",
+                "unique-filename",
+                "unpipe",
+                "update-notifier",
+                "uuid",
+                "validate-npm-package-license",
+                "validate-npm-package-name",
+                "which",
+                "worker-farm",
+                "write-file-atomic"
+            ],
+            "dependencies": {
+                "abbrev": "~1.1.1",
+                "ansicolors": "~0.3.2",
+                "ansistyles": "~0.1.3",
+                "aproba": "^2.0.0",
+                "archy": "~1.0.0",
+                "bin-links": "^1.1.7",
+                "bluebird": "^3.5.5",
+                "byte-size": "^5.0.1",
+                "cacache": "^12.0.3",
+                "call-limit": "^1.1.1",
+                "chownr": "^1.1.4",
+                "ci-info": "^2.0.0",
+                "cli-columns": "^3.1.2",
+                "cli-table3": "^0.5.1",
+                "cmd-shim": "^3.0.3",
+                "columnify": "~1.5.4",
+                "config-chain": "^1.1.12",
+                "debuglog": "*",
+                "detect-indent": "~5.0.0",
+                "detect-newline": "^2.1.0",
+                "dezalgo": "~1.0.3",
+                "editor": "~1.0.0",
+                "figgy-pudding": "^3.5.1",
+                "find-npm-prefix": "^1.0.2",
+                "fs-vacuum": "~1.2.10",
+                "fs-write-stream-atomic": "~1.0.10",
+                "gentle-fs": "^2.3.0",
+                "glob": "^7.1.6",
+                "graceful-fs": "^4.2.4",
+                "has-unicode": "~2.0.1",
+                "hosted-git-info": "^2.8.8",
+                "iferr": "^1.0.2",
+                "imurmurhash": "*",
+                "infer-owner": "^1.0.4",
+                "inflight": "~1.0.6",
+                "inherits": "^2.0.4",
+                "ini": "^1.3.5",
+                "init-package-json": "^1.10.3",
+                "is-cidr": "^3.0.0",
+                "json-parse-better-errors": "^1.0.2",
+                "JSONStream": "^1.3.5",
+                "lazy-property": "~1.0.0",
+                "libcipm": "^4.0.7",
+                "libnpm": "^3.0.1",
+                "libnpmaccess": "^3.0.2",
+                "libnpmhook": "^5.0.3",
+                "libnpmorg": "^1.0.1",
+                "libnpmsearch": "^2.0.2",
+                "libnpmteam": "^1.0.2",
+                "libnpx": "^10.2.2",
+                "lock-verify": "^2.1.0",
+                "lockfile": "^1.0.4",
+                "lodash._baseindexof": "*",
+                "lodash._baseuniq": "~4.6.0",
+                "lodash._bindcallback": "*",
+                "lodash._cacheindexof": "*",
+                "lodash._createcache": "*",
+                "lodash._getnative": "*",
+                "lodash.clonedeep": "~4.5.0",
+                "lodash.restparam": "*",
+                "lodash.union": "~4.6.0",
+                "lodash.uniq": "~4.5.0",
+                "lodash.without": "~4.4.0",
+                "lru-cache": "^5.1.1",
+                "meant": "~1.0.1",
+                "mississippi": "^3.0.0",
+                "mkdirp": "^0.5.5",
+                "move-concurrently": "^1.0.1",
+                "node-gyp": "^5.1.0",
+                "nopt": "^4.0.3",
+                "normalize-package-data": "^2.5.0",
+                "npm-audit-report": "^1.3.2",
+                "npm-cache-filename": "~1.0.2",
+                "npm-install-checks": "^3.0.2",
+                "npm-lifecycle": "^3.1.4",
+                "npm-package-arg": "^6.1.1",
+                "npm-packlist": "^1.4.8",
+                "npm-pick-manifest": "^3.0.2",
+                "npm-profile": "^4.0.4",
+                "npm-registry-fetch": "^4.0.4",
+                "npm-user-validate": "~1.0.0",
+                "npmlog": "~4.1.2",
+                "once": "~1.4.0",
+                "opener": "^1.5.1",
+                "osenv": "^0.1.5",
+                "pacote": "^9.5.12",
+                "path-is-inside": "~1.0.2",
+                "promise-inflight": "~1.0.1",
+                "qrcode-terminal": "^0.12.0",
+                "query-string": "^6.8.2",
+                "qw": "~1.0.1",
+                "read": "~1.0.7",
+                "read-cmd-shim": "^1.0.5",
+                "read-installed": "~4.0.3",
+                "read-package-json": "^2.1.1",
+                "read-package-tree": "^5.3.1",
+                "readable-stream": "^3.6.0",
+                "readdir-scoped-modules": "^1.1.0",
+                "request": "^2.88.0",
+                "retry": "^0.12.0",
+                "rimraf": "^2.7.1",
+                "safe-buffer": "^5.1.2",
+                "semver": "^5.7.1",
+                "sha": "^3.0.0",
+                "slide": "~1.1.6",
+                "sorted-object": "~2.0.1",
+                "sorted-union-stream": "~2.1.3",
+                "ssri": "^6.0.1",
+                "stringify-package": "^1.0.1",
+                "tar": "^4.4.13",
+                "text-table": "~0.2.0",
+                "tiny-relative-date": "^1.3.0",
+                "uid-number": "0.0.6",
+                "umask": "~1.1.0",
+                "unique-filename": "^1.1.1",
+                "unpipe": "~1.0.0",
+                "update-notifier": "^2.5.0",
+                "uuid": "^3.3.3",
+                "validate-npm-package-license": "^3.0.4",
+                "validate-npm-package-name": "~3.0.0",
+                "which": "^1.3.1",
+                "worker-farm": "^1.7.0",
+                "write-file-atomic": "^2.4.3"
+            },
+            "bin": {
+                "npm": "bin/npm-cli.js",
+                "npx": "bin/npx-cli.js"
+            },
+            "engines": {
+                "node": "6 >=6.2.0 || 8 || >=9.3.0"
+            }
+        },
+        "node_modules/npm-bundled": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
+            "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
+            "dependencies": {
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/npm-normalize-package-bin": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
+            "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
+        },
+        "node_modules/npm-packlist": {
+            "version": "1.4.8",
+            "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
+            "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
+            "dependencies": {
+                "ignore-walk": "^3.0.1",
+                "npm-bundled": "^1.0.1",
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "path-key": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/abbrev": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/agent-base": {
+            "version": "4.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "es6-promisify": "^5.0.0"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/agentkeepalive": {
+            "version": "3.5.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "humanize-ms": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/ajv": {
+            "version": "5.5.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "co": "^4.6.0",
+                "fast-deep-equal": "^1.0.0",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.3.0"
+            }
+        },
+        "node_modules/npm/node_modules/ansi-align": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "string-width": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/ansi-styles": {
+            "version": "3.2.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-convert": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/ansicolors": {
+            "version": "0.3.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/ansistyles": {
+            "version": "0.1.3",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/aproba": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/archy": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/are-we-there-yet": {
+            "version": "1.1.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "delegates": "^1.0.0",
+                "readable-stream": "^2.0.6"
+            }
+        },
+        "node_modules/npm/node_modules/are-we-there-yet/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/are-we-there-yet/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/asap": {
+            "version": "2.0.6",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/asn1": {
+            "version": "0.2.4",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": "~2.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/assert-plus": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/npm/node_modules/asynckit": {
+            "version": "0.4.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/aws-sign2": {
+            "version": "0.7.0",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/aws4": {
+            "version": "1.8.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/balanced-match": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/bcrypt-pbkdf": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "BSD-3-Clause",
+            "optional": true,
+            "dependencies": {
+                "tweetnacl": "^0.14.3"
+            }
+        },
+        "node_modules/npm/node_modules/bin-links": {
+            "version": "1.1.7",
+            "inBundle": true,
+            "license": "Artistic-2.0",
+            "dependencies": {
+                "bluebird": "^3.5.3",
+                "cmd-shim": "^3.0.0",
+                "gentle-fs": "^2.3.0",
+                "graceful-fs": "^4.1.15",
+                "npm-normalize-package-bin": "^1.0.0",
+                "write-file-atomic": "^2.3.0"
+            }
+        },
+        "node_modules/npm/node_modules/bluebird": {
+            "version": "3.5.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/boxen": {
+            "version": "1.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-align": "^2.0.0",
+                "camelcase": "^4.0.0",
+                "chalk": "^2.0.1",
+                "cli-boxes": "^1.0.0",
+                "string-width": "^2.0.0",
+                "term-size": "^1.2.0",
+                "widest-line": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/buffer-from": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/builtins": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/byline": {
+            "version": "5.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/byte-size": {
+            "version": "5.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/cacache": {
+            "version": "12.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "bluebird": "^3.5.5",
+                "chownr": "^1.1.1",
+                "figgy-pudding": "^3.5.1",
+                "glob": "^7.1.4",
+                "graceful-fs": "^4.1.15",
+                "infer-owner": "^1.0.3",
+                "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.3",
+                "ssri": "^6.0.1",
+                "unique-filename": "^1.1.1",
+                "y18n": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/call-limit": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/camelcase": {
+            "version": "4.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/capture-stack-trace": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/caseless": {
+            "version": "0.12.0",
+            "inBundle": true,
+            "license": "Apache-2.0"
+        },
+        "node_modules/npm/node_modules/chalk": {
+            "version": "2.4.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/chownr": {
+            "version": "1.1.4",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/ci-info": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/cidr-regex": {
+            "version": "2.0.10",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "ip-regex": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/cli-boxes": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/cli-columns": {
+            "version": "3.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "string-width": "^2.0.0",
+                "strip-ansi": "^3.0.1"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/npm/node_modules/cli-table3": {
+            "version": "0.5.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "object-assign": "^4.1.0",
+                "string-width": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            },
+            "optionalDependencies": {
+                "colors": "^1.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/cliui": {
+            "version": "4.1.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "string-width": "^2.1.1",
+                "strip-ansi": "^4.0.0",
+                "wrap-ansi": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/cliui/node_modules/ansi-regex": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/cliui/node_modules/strip-ansi": {
+            "version": "4.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/clone": {
+            "version": "1.0.4",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/npm/node_modules/cmd-shim": {
+            "version": "3.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "mkdirp": "~0.5.0"
+            }
+        },
+        "node_modules/npm/node_modules/co": {
+            "version": "4.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "iojs": ">= 1.0.0",
+                "node": ">= 0.12.0"
+            }
+        },
+        "node_modules/npm/node_modules/code-point-at": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/color-convert": {
+            "version": "1.9.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-name": "^1.1.1"
+            }
+        },
+        "node_modules/npm/node_modules/color-name": {
+            "version": "1.1.3",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/colors": {
+            "version": "1.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "engines": {
+                "node": ">=0.1.90"
+            }
+        },
+        "node_modules/npm/node_modules/columnify": {
+            "version": "1.5.4",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "strip-ansi": "^3.0.0",
+                "wcwidth": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/combined-stream": {
+            "version": "1.0.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "delayed-stream": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/npm/node_modules/concat-map": {
+            "version": "0.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/concat-stream": {
+            "version": "1.6.2",
+            "engines": [
+                "node >= 0.8"
+            ],
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "buffer-from": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.2.2",
+                "typedarray": "^0.0.6"
+            }
+        },
+        "node_modules/npm/node_modules/concat-stream/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/concat-stream/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/config-chain": {
+            "version": "1.1.12",
+            "inBundle": true,
+            "dependencies": {
+                "ini": "^1.3.4",
+                "proto-list": "~1.2.1"
+            }
+        },
+        "node_modules/npm/node_modules/configstore": {
+            "version": "3.1.2",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "dot-prop": "^4.1.0",
+                "graceful-fs": "^4.1.2",
+                "make-dir": "^1.0.0",
+                "unique-string": "^1.0.0",
+                "write-file-atomic": "^2.0.0",
+                "xdg-basedir": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/console-control-strings": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/copy-concurrently": {
+            "version": "1.0.5",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/copy-concurrently/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/copy-concurrently/node_modules/iferr": {
+            "version": "0.1.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/core-util-is": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/create-error-class": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "capture-stack-trace": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/cross-spawn": {
+            "version": "5.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "lru-cache": "^4.0.1",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            }
+        },
+        "node_modules/npm/node_modules/cross-spawn/node_modules/lru-cache": {
+            "version": "4.1.5",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "pseudomap": "^1.0.2",
+                "yallist": "^2.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/cross-spawn/node_modules/yallist": {
+            "version": "2.1.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/crypto-random-string": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/cyclist": {
+            "version": "0.2.2",
+            "inBundle": true
+        },
+        "node_modules/npm/node_modules/dashdash": {
+            "version": "1.14.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert-plus": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/npm/node_modules/debug": {
+            "version": "3.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/debug/node_modules/ms": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/debuglog": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/decamelize": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/decode-uri-component": {
+            "version": "0.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/npm/node_modules/deep-extend": {
+            "version": "0.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/defaults": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "clone": "^1.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/define-properties": {
+            "version": "1.1.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "object-keys": "^1.0.12"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/delayed-stream": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/npm/node_modules/delegates": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/detect-indent": {
+            "version": "5.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/detect-newline": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/dezalgo": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "asap": "^2.0.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/npm/node_modules/dot-prop": {
+            "version": "4.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-obj": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/dotenv": {
+            "version": "5.0.1",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "engines": {
+                "node": ">=4.6.0"
+            }
+        },
+        "node_modules/npm/node_modules/duplexer3": {
+            "version": "0.1.4",
+            "inBundle": true,
+            "license": "BSD-3-Clause"
+        },
+        "node_modules/npm/node_modules/duplexify": {
+            "version": "3.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "end-of-stream": "^1.0.0",
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/duplexify/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/duplexify/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/ecc-jsbn": {
+            "version": "0.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "jsbn": "~0.1.0",
+                "safer-buffer": "^2.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/editor": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/encoding": {
+            "version": "0.1.12",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "iconv-lite": "~0.4.13"
+            }
+        },
+        "node_modules/npm/node_modules/end-of-stream": {
+            "version": "1.4.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "once": "^1.4.0"
+            }
+        },
+        "node_modules/npm/node_modules/env-paths": {
+            "version": "2.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/err-code": {
+            "version": "1.1.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/errno": {
+            "version": "0.1.7",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "prr": "~1.0.1"
+            },
+            "bin": {
+                "errno": "cli.js"
+            }
+        },
+        "node_modules/npm/node_modules/es-abstract": {
+            "version": "1.12.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-to-primitive": "^1.1.1",
+                "function-bind": "^1.1.1",
+                "has": "^1.0.1",
+                "is-callable": "^1.1.3",
+                "is-regex": "^1.0.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/es-to-primitive": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-callable": "^1.1.4",
+                "is-date-object": "^1.0.1",
+                "is-symbol": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/es6-promise": {
+            "version": "4.2.8",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/es6-promisify": {
+            "version": "5.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "es6-promise": "^4.0.3"
+            }
+        },
+        "node_modules/npm/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/npm/node_modules/execa": {
+            "version": "0.7.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "cross-spawn": "^5.0.1",
+                "get-stream": "^3.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"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/execa/node_modules/get-stream": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/extend": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/extsprintf": {
+            "version": "1.3.0",
+            "engines": [
+                "node >=0.6.0"
+            ],
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/fast-deep-equal": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/fast-json-stable-stringify": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/figgy-pudding": {
+            "version": "3.5.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/find-npm-prefix": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/find-up": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "locate-path": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/flush-write-stream": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.4"
+            }
+        },
+        "node_modules/npm/node_modules/flush-write-stream/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/flush-write-stream/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/forever-agent": {
+            "version": "0.6.1",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/form-data": {
+            "version": "2.3.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "1.0.6",
+                "mime-types": "^2.1.12"
+            },
+            "engines": {
+                "node": ">= 0.12"
+            }
+        },
+        "node_modules/npm/node_modules/from2": {
+            "version": "2.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/from2/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/from2/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/fs-minipass": {
+            "version": "1.2.7",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "minipass": "^2.6.0"
+            }
+        },
+        "node_modules/npm/node_modules/fs-minipass/node_modules/minipass": {
+            "version": "2.9.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/fs-vacuum": {
+            "version": "1.2.10",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "path-is-inside": "^1.0.1",
+                "rimraf": "^2.5.2"
+            }
+        },
+        "node_modules/npm/node_modules/fs-write-stream-atomic": {
+            "version": "1.0.10",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "iferr": "^0.1.5",
+                "imurmurhash": "^0.1.4",
+                "readable-stream": "1 || 2"
+            }
+        },
+        "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/iferr": {
+            "version": "0.1.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/fs-write-stream-atomic/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/function-bind": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/gauge": {
+            "version": "2.7.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/gauge/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/gauge/node_modules/string-width": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/genfun": {
+            "version": "5.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/gentle-fs": {
+            "version": "2.3.0",
+            "inBundle": true,
+            "license": "Artistic-2.0",
+            "dependencies": {
+                "aproba": "^1.1.2",
+                "chownr": "^1.1.2",
+                "cmd-shim": "^3.0.3",
+                "fs-vacuum": "^1.2.10",
+                "graceful-fs": "^4.1.11",
+                "iferr": "^0.1.5",
+                "infer-owner": "^1.0.4",
+                "mkdirp": "^0.5.1",
+                "path-is-inside": "^1.0.2",
+                "read-cmd-shim": "^1.0.1",
+                "slide": "^1.1.6"
+            }
+        },
+        "node_modules/npm/node_modules/gentle-fs/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/gentle-fs/node_modules/iferr": {
+            "version": "0.1.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/get-caller-file": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/get-stream": {
+            "version": "4.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "pump": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/getpass": {
+            "version": "0.1.7",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert-plus": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/glob": {
+            "version": "7.1.6",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/npm/node_modules/global-dirs": {
+            "version": "0.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ini": "^1.3.4"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/got": {
+            "version": "6.7.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "create-error-class": "^3.0.0",
+                "duplexer3": "^0.1.4",
+                "get-stream": "^3.0.0",
+                "is-redirect": "^1.0.0",
+                "is-retry-allowed": "^1.0.0",
+                "is-stream": "^1.0.0",
+                "lowercase-keys": "^1.0.0",
+                "safe-buffer": "^5.0.1",
+                "timed-out": "^4.0.0",
+                "unzip-response": "^2.0.1",
+                "url-parse-lax": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/got/node_modules/get-stream": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/graceful-fs": {
+            "version": "4.2.4",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/har-schema": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/har-validator": {
+            "version": "5.1.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "ajv": "^5.3.0",
+                "har-schema": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/has": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "function-bind": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/npm/node_modules/has-flag": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/has-symbols": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/has-unicode": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/hosted-git-info": {
+            "version": "2.8.8",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/http-cache-semantics": {
+            "version": "3.8.1",
+            "inBundle": true,
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/npm/node_modules/http-proxy-agent": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "4",
+                "debug": "3.1.0"
+            },
+            "engines": {
+                "node": ">= 4.5.0"
+            }
+        },
+        "node_modules/npm/node_modules/http-signature": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert-plus": "^1.0.0",
+                "jsprim": "^1.2.2",
+                "sshpk": "^1.7.0"
+            },
+            "engines": {
+                "node": ">=0.8",
+                "npm": ">=1.3.7"
+            }
+        },
+        "node_modules/npm/node_modules/https-proxy-agent": {
+            "version": "2.2.4",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "^4.3.0",
+                "debug": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4.5.0"
+            }
+        },
+        "node_modules/npm/node_modules/humanize-ms": {
+            "version": "1.2.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ms": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/iconv-lite": {
+            "version": "0.4.23",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/iferr": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/ignore-walk": {
+            "version": "3.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "minimatch": "^3.0.4"
+            }
+        },
+        "node_modules/npm/node_modules/import-lazy": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/imurmurhash": {
+            "version": "0.1.4",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.8.19"
+            }
+        },
+        "node_modules/npm/node_modules/infer-owner": {
+            "version": "1.0.4",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/inflight": {
+            "version": "1.0.6",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/npm/node_modules/inherits": {
+            "version": "2.0.4",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/ini": {
+            "version": "1.3.5",
+            "inBundle": true,
+            "license": "ISC",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/init-package-json": {
+            "version": "1.10.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "glob": "^7.1.1",
+                "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0",
+                "promzard": "^0.3.0",
+                "read": "~1.0.1",
+                "read-package-json": "1 || 2",
+                "semver": "2.x || 3.x || 4 || 5",
+                "validate-npm-package-license": "^3.0.1",
+                "validate-npm-package-name": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/invert-kv": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/ip": {
+            "version": "1.1.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/ip-regex": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/is-callable": {
+            "version": "1.1.4",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/is-ci": {
+            "version": "1.2.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ci-info": "^1.5.0"
+            },
+            "bin": {
+                "is-ci": "bin.js"
+            }
+        },
+        "node_modules/npm/node_modules/is-ci/node_modules/ci-info": {
+            "version": "1.6.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/is-cidr": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "cidr-regex": "^2.0.10"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/is-date-object": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/is-fullwidth-code-point": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "number-is-nan": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-installed-globally": {
+            "version": "0.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "global-dirs": "^0.1.0",
+                "is-path-inside": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/is-npm": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-obj": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-path-inside": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "path-is-inside": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-redirect": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-regex": {
+            "version": "1.0.4",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "has": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/is-retry-allowed": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-stream": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/is-symbol": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-symbols": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/is-typedarray": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/isarray": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/isexe": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/isstream": {
+            "version": "0.1.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/jsbn": {
+            "version": "0.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "optional": true
+        },
+        "node_modules/npm/node_modules/json-parse-better-errors": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/json-schema": {
+            "version": "0.2.3",
+            "inBundle": true
+        },
+        "node_modules/npm/node_modules/json-schema-traverse": {
+            "version": "0.3.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/json-stringify-safe": {
+            "version": "5.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/jsonparse": {
+            "version": "1.3.1",
+            "engines": [
+                "node >= 0.2.0"
+            ],
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/JSONStream": {
+            "version": "1.3.5",
+            "inBundle": true,
+            "license": "(MIT OR Apache-2.0)",
+            "dependencies": {
+                "jsonparse": "^1.2.0",
+                "through": ">=2.2.7 <3"
+            },
+            "bin": {
+                "JSONStream": "bin.js"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/jsprim": {
+            "version": "1.4.1",
+            "engines": [
+                "node >=0.6.0"
+            ],
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert-plus": "1.0.0",
+                "extsprintf": "1.3.0",
+                "json-schema": "0.2.3",
+                "verror": "1.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/latest-version": {
+            "version": "3.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "package-json": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/lazy-property": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lcid": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "invert-kv": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libcipm": {
+            "version": "4.0.7",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "bin-links": "^1.1.2",
+                "bluebird": "^3.5.1",
+                "figgy-pudding": "^3.5.1",
+                "find-npm-prefix": "^1.0.2",
+                "graceful-fs": "^4.1.11",
+                "ini": "^1.3.5",
+                "lock-verify": "^2.0.2",
+                "mkdirp": "^0.5.1",
+                "npm-lifecycle": "^3.0.0",
+                "npm-logical-tree": "^1.2.1",
+                "npm-package-arg": "^6.1.0",
+                "pacote": "^9.1.0",
+                "read-package-json": "^2.0.13",
+                "rimraf": "^2.6.2",
+                "worker-farm": "^1.6.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpm": {
+            "version": "3.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "bin-links": "^1.1.2",
+                "bluebird": "^3.5.3",
+                "find-npm-prefix": "^1.0.2",
+                "libnpmaccess": "^3.0.2",
+                "libnpmconfig": "^1.2.1",
+                "libnpmhook": "^5.0.3",
+                "libnpmorg": "^1.0.1",
+                "libnpmpublish": "^1.1.2",
+                "libnpmsearch": "^2.0.2",
+                "libnpmteam": "^1.0.2",
+                "lock-verify": "^2.0.2",
+                "npm-lifecycle": "^3.0.0",
+                "npm-logical-tree": "^1.2.1",
+                "npm-package-arg": "^6.1.0",
+                "npm-profile": "^4.0.2",
+                "npm-registry-fetch": "^4.0.0",
+                "npmlog": "^4.1.2",
+                "pacote": "^9.5.3",
+                "read-package-json": "^2.0.13",
+                "stringify-package": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmaccess": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^2.0.0",
+                "get-stream": "^4.0.0",
+                "npm-package-arg": "^6.1.0",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig": {
+            "version": "1.2.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "figgy-pudding": "^3.5.1",
+                "find-up": "^3.0.0",
+                "ini": "^1.3.5"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig/node_modules/find-up": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "locate-path": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig/node_modules/locate-path": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-locate": "^3.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig/node_modules/p-limit": {
+            "version": "2.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-try": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig/node_modules/p-locate": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-limit": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmconfig/node_modules/p-try": {
+            "version": "2.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmhook": {
+            "version": "5.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^2.0.0",
+                "figgy-pudding": "^3.4.1",
+                "get-stream": "^4.0.0",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmorg": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^2.0.0",
+                "figgy-pudding": "^3.4.1",
+                "get-stream": "^4.0.0",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmpublish": {
+            "version": "1.1.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^2.0.0",
+                "figgy-pudding": "^3.5.1",
+                "get-stream": "^4.0.0",
+                "lodash.clonedeep": "^4.5.0",
+                "normalize-package-data": "^2.4.0",
+                "npm-package-arg": "^6.1.0",
+                "npm-registry-fetch": "^4.0.0",
+                "semver": "^5.5.1",
+                "ssri": "^6.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmsearch": {
+            "version": "2.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "figgy-pudding": "^3.5.1",
+                "get-stream": "^4.0.0",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpmteam": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^2.0.0",
+                "figgy-pudding": "^3.4.1",
+                "get-stream": "^4.0.0",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/libnpx": {
+            "version": "10.2.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "dotenv": "^5.0.1",
+                "npm-package-arg": "^6.0.0",
+                "rimraf": "^2.6.2",
+                "safe-buffer": "^5.1.0",
+                "update-notifier": "^2.3.0",
+                "which": "^1.3.0",
+                "y18n": "^4.0.0",
+                "yargs": "^11.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/locate-path": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-locate": "^2.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/lock-verify": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "npm-package-arg": "^6.1.0",
+                "semver": "^5.4.1"
+            }
+        },
+        "node_modules/npm/node_modules/lockfile": {
+            "version": "1.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "signal-exit": "^3.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/lodash._baseindexof": {
+            "version": "3.1.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash._baseuniq": {
+            "version": "4.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "lodash._createset": "~4.0.0",
+                "lodash._root": "~3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/lodash._bindcallback": {
+            "version": "3.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash._cacheindexof": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash._createcache": {
+            "version": "3.1.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "lodash._getnative": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/lodash._createset": {
+            "version": "4.0.3",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash._getnative": {
+            "version": "3.9.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash._root": {
+            "version": "3.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash.clonedeep": {
+            "version": "4.5.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash.restparam": {
+            "version": "3.6.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash.union": {
+            "version": "4.6.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash.uniq": {
+            "version": "4.5.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lodash.without": {
+            "version": "4.4.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/lowercase-keys": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/lru-cache": {
+            "version": "5.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "yallist": "^3.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/make-dir": {
+            "version": "1.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "pify": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/make-fetch-happen": {
+            "version": "5.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "agentkeepalive": "^3.4.1",
+                "cacache": "^12.0.0",
+                "http-cache-semantics": "^3.8.1",
+                "http-proxy-agent": "^2.1.0",
+                "https-proxy-agent": "^2.2.3",
+                "lru-cache": "^5.1.1",
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/map-age-cleaner": {
+            "version": "0.1.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-defer": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/meant": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/mem": {
+            "version": "4.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "map-age-cleaner": "^0.1.1",
+                "mimic-fn": "^2.0.0",
+                "p-is-promise": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/mem/node_modules/mimic-fn": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/mime-db": {
+            "version": "1.35.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/npm/node_modules/mime-types": {
+            "version": "2.1.19",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "mime-db": "~1.35.0"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/npm/node_modules/minimatch": {
+            "version": "3.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/minizlib": {
+            "version": "1.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "minipass": "^2.9.0"
+            }
+        },
+        "node_modules/npm/node_modules/minizlib/node_modules/minipass": {
+            "version": "2.9.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/mississippi": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/mkdirp": {
+            "version": "0.5.5",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "minimist": "^1.2.5"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/npm/node_modules/mkdirp/node_modules/minimist": {
+            "version": "1.2.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/move-concurrently": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/move-concurrently/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/ms": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/mute-stream": {
+            "version": "0.0.7",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/nice-try": {
+            "version": "1.0.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/node-fetch-npm": {
+            "version": "2.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "encoding": "^0.1.11",
+                "json-parse-better-errors": "^1.0.0",
+                "safe-buffer": "^5.1.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/node-gyp": {
+            "version": "5.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "env-paths": "^2.2.0",
+                "glob": "^7.1.4",
+                "graceful-fs": "^4.2.2",
+                "mkdirp": "^0.5.1",
+                "nopt": "^4.0.1",
+                "npmlog": "^4.1.2",
+                "request": "^2.88.0",
+                "rimraf": "^2.6.3",
+                "semver": "^5.7.1",
+                "tar": "^4.4.12",
+                "which": "^1.3.1"
+            },
+            "bin": {
+                "node-gyp": "bin/node-gyp.js"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/nopt": {
+            "version": "4.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "abbrev": "1",
+                "osenv": "^0.1.4"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            }
+        },
+        "node_modules/npm/node_modules/normalize-package-data": {
+            "version": "2.5.0",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "hosted-git-info": "^2.1.4",
+                "resolve": "^1.10.0",
+                "semver": "2 || 3 || 4 || 5",
+                "validate-npm-package-license": "^3.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/normalize-package-data/node_modules/resolve": {
+            "version": "1.10.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "path-parse": "^1.0.6"
+            }
+        },
+        "node_modules/npm/node_modules/npm-audit-report": {
+            "version": "1.3.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "cli-table3": "^0.5.0",
+                "console-control-strings": "^1.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/npm-bundled": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/npm-cache-filename": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/npm-install-checks": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "semver": "^2.3.0 || 3.x || 4 || 5"
+            }
+        },
+        "node_modules/npm/node_modules/npm-lifecycle": {
+            "version": "3.1.4",
+            "inBundle": true,
+            "license": "Artistic-2.0",
+            "dependencies": {
+                "byline": "^5.0.0",
+                "graceful-fs": "^4.1.15",
+                "node-gyp": "^5.0.2",
+                "resolve-from": "^4.0.0",
+                "slide": "^1.1.6",
+                "uid-number": "0.0.6",
+                "umask": "^1.1.0",
+                "which": "^1.3.1"
+            }
+        },
+        "node_modules/npm/node_modules/npm-logical-tree": {
+            "version": "1.2.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/npm-normalize-package-bin": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/npm-package-arg": {
+            "version": "6.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "hosted-git-info": "^2.7.1",
+                "osenv": "^0.1.5",
+                "semver": "^5.6.0",
+                "validate-npm-package-name": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/npm-packlist": {
+            "version": "1.4.8",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "ignore-walk": "^3.0.1",
+                "npm-bundled": "^1.0.1",
+                "npm-normalize-package-bin": "^1.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/npm-pick-manifest": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "figgy-pudding": "^3.5.1",
+                "npm-package-arg": "^6.0.0",
+                "semver": "^5.4.1"
+            }
+        },
+        "node_modules/npm/node_modules/npm-profile": {
+            "version": "4.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^1.1.2 || 2",
+                "figgy-pudding": "^3.4.1",
+                "npm-registry-fetch": "^4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/npm-registry-fetch": {
+            "version": "4.0.4",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "bluebird": "^3.5.1",
+                "figgy-pudding": "^3.4.1",
+                "JSONStream": "^1.3.4",
+                "lru-cache": "^5.1.1",
+                "make-fetch-happen": "^5.0.0",
+                "npm-package-arg": "^6.1.0",
+                "safe-buffer": "^5.2.0"
+            }
+        },
+        "node_modules/npm/node_modules/npm-registry-fetch/node_modules/safe-buffer": {
+            "version": "5.2.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/npm-run-path": {
+            "version": "2.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "path-key": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/npm-user-validate": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "BSD-2-Clause"
+        },
+        "node_modules/npm/node_modules/npmlog": {
+            "version": "4.1.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "are-we-there-yet": "~1.1.2",
+                "console-control-strings": "~1.1.0",
+                "gauge": "~2.7.3",
+                "set-blocking": "~2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/number-is-nan": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/oauth-sign": {
+            "version": "0.9.0",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/object-assign": {
+            "version": "4.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/object-keys": {
+            "version": "1.0.12",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/npm/node_modules/object.getownpropertydescriptors": {
+            "version": "2.0.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "define-properties": "^1.1.2",
+                "es-abstract": "^1.5.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/npm/node_modules/once": {
+            "version": "1.4.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/npm/node_modules/opener": {
+            "version": "1.5.1",
+            "inBundle": true,
+            "license": "(WTFPL OR MIT)",
+            "bin": {
+                "opener": "bin/opener-bin.js"
+            }
+        },
+        "node_modules/npm/node_modules/os-homedir": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/os-locale": {
+            "version": "3.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "execa": "^1.0.0",
+                "lcid": "^2.0.0",
+                "mem": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/os-locale/node_modules/cross-spawn": {
+            "version": "6.0.5",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "nice-try": "^1.0.4",
+                "path-key": "^2.0.1",
+                "semver": "^5.5.0",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            },
+            "engines": {
+                "node": ">=4.8"
+            }
+        },
+        "node_modules/npm/node_modules/os-locale/node_modules/execa": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/os-tmpdir": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/osenv": {
+            "version": "0.1.5",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "os-homedir": "^1.0.0",
+                "os-tmpdir": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/p-defer": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/p-finally": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/p-is-promise": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/p-limit": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-try": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/p-locate": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "p-limit": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/p-try": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/package-json": {
+            "version": "4.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "got": "^6.7.1",
+                "registry-auth-token": "^3.0.1",
+                "registry-url": "^3.0.3",
+                "semver": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/pacote": {
+            "version": "9.5.12",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "bluebird": "^3.5.3",
+                "cacache": "^12.0.2",
+                "chownr": "^1.1.2",
+                "figgy-pudding": "^3.5.1",
+                "get-stream": "^4.1.0",
+                "glob": "^7.1.3",
+                "infer-owner": "^1.0.4",
+                "lru-cache": "^5.1.1",
+                "make-fetch-happen": "^5.0.0",
+                "minimatch": "^3.0.4",
+                "minipass": "^2.3.5",
+                "mississippi": "^3.0.0",
+                "mkdirp": "^0.5.1",
+                "normalize-package-data": "^2.4.0",
+                "npm-normalize-package-bin": "^1.0.0",
+                "npm-package-arg": "^6.1.0",
+                "npm-packlist": "^1.1.12",
+                "npm-pick-manifest": "^3.0.0",
+                "npm-registry-fetch": "^4.0.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.10",
+                "unique-filename": "^1.1.1",
+                "which": "^1.3.1"
+            }
+        },
+        "node_modules/npm/node_modules/pacote/node_modules/minipass": {
+            "version": "2.9.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/parallel-transform": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "cyclist": "~0.2.2",
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.1.5"
+            }
+        },
+        "node_modules/npm/node_modules/parallel-transform/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/parallel-transform/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/path-exists": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/path-is-absolute": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/path-is-inside": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "(WTFPL OR MIT)"
+        },
+        "node_modules/npm/node_modules/path-key": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/path-parse": {
+            "version": "1.0.6",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/performance-now": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/pify": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/prepend-http": {
+            "version": "1.0.4",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/process-nextick-args": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/promise-inflight": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/promise-retry": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "err-code": "^1.0.0",
+                "retry": "^0.10.0"
+            },
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
+        "node_modules/npm/node_modules/promise-retry/node_modules/retry": {
+            "version": "0.10.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/promzard": {
+            "version": "0.3.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "read": "1"
+            }
+        },
+        "node_modules/npm/node_modules/proto-list": {
+            "version": "1.2.4",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/protoduck": {
+            "version": "5.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "genfun": "^5.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/prr": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/pseudomap": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/psl": {
+            "version": "1.1.29",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/pump": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/npm/node_modules/pumpify": {
+            "version": "1.5.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "duplexify": "^3.6.0",
+                "inherits": "^2.0.3",
+                "pump": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/pumpify/node_modules/pump": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/npm/node_modules/punycode": {
+            "version": "1.4.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/qrcode-terminal": {
+            "version": "0.12.0",
+            "inBundle": true,
+            "bin": {
+                "qrcode-terminal": "bin/qrcode-terminal.js"
+            }
+        },
+        "node_modules/npm/node_modules/qs": {
+            "version": "6.5.2",
+            "inBundle": true,
+            "license": "BSD-3-Clause",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/npm/node_modules/query-string": {
+            "version": "6.8.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "decode-uri-component": "^0.2.0",
+                "split-on-first": "^1.0.0",
+                "strict-uri-encode": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/qw": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/rc": {
+            "version": "1.2.8",
+            "inBundle": true,
+            "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/npm/node_modules/rc/node_modules/minimist": {
+            "version": "1.2.5",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/read": {
+            "version": "1.0.7",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "mute-stream": "~0.0.4"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/npm/node_modules/read-cmd-shim": {
+            "version": "1.0.5",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "graceful-fs": "^4.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/read-installed": {
+            "version": "4.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "debuglog": "^1.0.1",
+                "read-package-json": "^2.0.0",
+                "readdir-scoped-modules": "^1.0.0",
+                "semver": "2 || 3 || 4 || 5",
+                "slide": "~1.1.3",
+                "util-extend": "^1.0.1"
+            },
+            "optionalDependencies": {
+                "graceful-fs": "^4.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/read-package-json": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "glob": "^7.1.1",
+                "json-parse-better-errors": "^1.0.1",
+                "normalize-package-data": "^2.0.0",
+                "npm-normalize-package-bin": "^1.0.0"
+            },
+            "optionalDependencies": {
+                "graceful-fs": "^4.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/read-package-tree": {
+            "version": "5.3.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "read-package-json": "^2.0.0",
+                "readdir-scoped-modules": "^1.0.0",
+                "util-promisify": "^2.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/readable-stream": {
+            "version": "3.6.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/npm/node_modules/readdir-scoped-modules": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "debuglog": "^1.0.1",
+                "dezalgo": "^1.0.0",
+                "graceful-fs": "^4.1.2",
+                "once": "^1.3.0"
+            }
+        },
+        "node_modules/npm/node_modules/registry-auth-token": {
+            "version": "3.4.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "rc": "^1.1.6",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/registry-url": {
+            "version": "3.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "rc": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/request": {
+            "version": "2.88.0",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/npm/node_modules/require-directory": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/require-main-filename": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/resolve-from": {
+            "version": "4.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/retry": {
+            "version": "0.12.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/npm/node_modules/rimraf": {
+            "version": "2.7.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/npm/node_modules/run-queue": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "aproba": "^1.1.1"
+            }
+        },
+        "node_modules/npm/node_modules/run-queue/node_modules/aproba": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/semver": {
+            "version": "5.7.1",
+            "inBundle": true,
+            "license": "ISC",
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/npm/node_modules/semver-diff": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "semver": "^5.0.3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/set-blocking": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/sha": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "(BSD-2-Clause OR MIT)",
+            "dependencies": {
+                "graceful-fs": "^4.1.2"
+            }
+        },
+        "node_modules/npm/node_modules/shebang-command": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "shebang-regex": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/shebang-regex": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/signal-exit": {
+            "version": "3.0.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/slide": {
+            "version": "1.1.6",
+            "inBundle": true,
+            "license": "ISC",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/smart-buffer": {
+            "version": "4.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 6.0.0",
+                "npm": ">= 3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/socks": {
+            "version": "2.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ip": "1.1.5",
+                "smart-buffer": "^4.1.0"
+            },
+            "engines": {
+                "node": ">= 6.0.0",
+                "npm": ">= 3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/socks-proxy-agent": {
+            "version": "4.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "agent-base": "~4.2.1",
+                "socks": "~2.3.2"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/npm/node_modules/socks-proxy-agent/node_modules/agent-base": {
+            "version": "4.2.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "es6-promisify": "^5.0.0"
+            },
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/sorted-object": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "(WTFPL OR MIT)"
+        },
+        "node_modules/npm/node_modules/sorted-union-stream": {
+            "version": "2.1.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "from2": "^1.3.0",
+                "stream-iterate": "^1.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/sorted-union-stream/node_modules/from2": {
+            "version": "1.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "inherits": "~2.0.1",
+                "readable-stream": "~1.1.10"
+            }
+        },
+        "node_modules/npm/node_modules/sorted-union-stream/node_modules/isarray": {
+            "version": "0.0.1",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/sorted-union-stream/node_modules/readable-stream": {
+            "version": "1.1.14",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.1",
+                "isarray": "0.0.1",
+                "string_decoder": "~0.10.x"
+            }
+        },
+        "node_modules/npm/node_modules/sorted-union-stream/node_modules/string_decoder": {
+            "version": "0.10.31",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/spdx-correct": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "spdx-expression-parse": "^3.0.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/spdx-exceptions": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "CC-BY-3.0"
+        },
+        "node_modules/npm/node_modules/spdx-expression-parse": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "spdx-exceptions": "^2.1.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/spdx-license-ids": {
+            "version": "3.0.3",
+            "inBundle": true,
+            "license": "CC0-1.0"
+        },
+        "node_modules/npm/node_modules/split-on-first": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/npm/node_modules/sshpk": {
+            "version": "1.14.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "asn1": "~0.2.3",
+                "assert-plus": "^1.0.0",
+                "dashdash": "^1.12.0",
+                "getpass": "^0.1.1",
+                "safer-buffer": "^2.0.2"
+            },
+            "bin": {
+                "sshpk-conv": "bin/sshpk-conv",
+                "sshpk-sign": "bin/sshpk-sign",
+                "sshpk-verify": "bin/sshpk-verify"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            },
+            "optionalDependencies": {
+                "bcrypt-pbkdf": "^1.0.0",
+                "ecc-jsbn": "~0.1.1",
+                "jsbn": "~0.1.0",
+                "tweetnacl": "~0.14.0"
+            }
+        },
+        "node_modules/npm/node_modules/ssri": {
+            "version": "6.0.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "figgy-pudding": "^3.5.1"
+            }
+        },
+        "node_modules/npm/node_modules/stream-each": {
+            "version": "1.2.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/stream-iterate": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "^2.1.5",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/stream-iterate/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/stream-iterate/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/stream-shift": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/strict-uri-encode": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/string_decoder": {
+            "version": "1.3.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.2.0"
+            }
+        },
+        "node_modules/npm/node_modules/string_decoder/node_modules/safe-buffer": {
+            "version": "5.2.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/string-width": {
+            "version": "2.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/string-width/node_modules/is-fullwidth-code-point": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": {
+            "version": "4.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/stringify-package": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/strip-ansi": {
+            "version": "3.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/strip-eof": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/supports-color": {
+            "version": "5.4.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/tar": {
+            "version": "4.4.13",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "fs-minipass": "^1.2.5",
+                "minipass": "^2.8.6",
+                "minizlib": "^1.2.1",
+                "mkdirp": "^0.5.0",
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=4.5"
+            }
+        },
+        "node_modules/npm/node_modules/tar/node_modules/minipass": {
+            "version": "2.9.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/term-size": {
+            "version": "1.2.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "execa": "^0.7.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/text-table": {
+            "version": "0.2.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/through": {
+            "version": "2.3.8",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/through2": {
+            "version": "2.0.3",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "readable-stream": "^2.1.5",
+                "xtend": "~4.0.1"
+            }
+        },
+        "node_modules/npm/node_modules/through2/node_modules/readable-stream": {
+            "version": "2.3.6",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/npm/node_modules/through2/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/timed-out": {
+            "version": "4.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/tiny-relative-date": {
+            "version": "1.3.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/tough-cookie": {
+            "version": "2.4.3",
+            "inBundle": true,
+            "license": "BSD-3-Clause",
+            "dependencies": {
+                "psl": "^1.1.24",
+                "punycode": "^1.4.1"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/npm/node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/tweetnacl": {
+            "version": "0.14.5",
+            "inBundle": true,
+            "license": "Unlicense",
+            "optional": true
+        },
+        "node_modules/npm/node_modules/typedarray": {
+            "version": "0.0.6",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/uid-number": {
+            "version": "0.0.6",
+            "inBundle": true,
+            "license": "ISC",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/npm/node_modules/umask": {
+            "version": "1.1.0",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/unique-filename": {
+            "version": "1.1.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "unique-slug": "^2.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/unique-slug": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "imurmurhash": "^0.1.4"
+            }
+        },
+        "node_modules/npm/node_modules/unique-string": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "crypto-random-string": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/unpipe": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/npm/node_modules/unzip-response": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/update-notifier": {
+            "version": "2.5.0",
+            "inBundle": true,
+            "license": "BSD-2-Clause",
+            "dependencies": {
+                "boxen": "^1.2.1",
+                "chalk": "^2.0.1",
+                "configstore": "^3.0.0",
+                "import-lazy": "^2.1.0",
+                "is-ci": "^1.0.10",
+                "is-installed-globally": "^0.1.0",
+                "is-npm": "^1.0.0",
+                "latest-version": "^3.0.0",
+                "semver-diff": "^2.0.0",
+                "xdg-basedir": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/url-parse-lax": {
+            "version": "1.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "prepend-http": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/util-extend": {
+            "version": "1.0.3",
+            "inBundle": true,
+            "license": "MIT"
+        },
+        "node_modules/npm/node_modules/util-promisify": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "object.getownpropertydescriptors": "^2.0.3"
+            }
+        },
+        "node_modules/npm/node_modules/uuid": {
+            "version": "3.3.3",
+            "inBundle": true,
+            "license": "MIT",
+            "bin": {
+                "uuid": "bin/uuid"
+            }
+        },
+        "node_modules/npm/node_modules/validate-npm-package-license": {
+            "version": "3.0.4",
+            "inBundle": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "spdx-correct": "^3.0.0",
+                "spdx-expression-parse": "^3.0.0"
+            }
+        },
+        "node_modules/npm/node_modules/validate-npm-package-name": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "builtins": "^1.0.3"
+            }
+        },
+        "node_modules/npm/node_modules/verror": {
+            "version": "1.10.0",
+            "engines": [
+                "node >=0.6.0"
+            ],
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "assert-plus": "^1.0.0",
+                "core-util-is": "1.0.2",
+                "extsprintf": "^1.2.0"
+            }
+        },
+        "node_modules/npm/node_modules/wcwidth": {
+            "version": "1.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "defaults": "^1.0.3"
+            }
+        },
+        "node_modules/npm/node_modules/which": {
+            "version": "1.3.1",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "isexe": "^2.0.0"
+            },
+            "bin": {
+                "which": "bin/which"
+            }
+        },
+        "node_modules/npm/node_modules/which-module": {
+            "version": "2.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/wide-align": {
+            "version": "1.1.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "string-width": "^1.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/wide-align/node_modules/string-width": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/widest-line": {
+            "version": "2.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "string-width": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/worker-farm": {
+            "version": "1.7.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "errno": "~0.1.7"
+            }
+        },
+        "node_modules/npm/node_modules/wrap-ansi": {
+            "version": "2.1.0",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "string-width": "^1.0.1",
+                "strip-ansi": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "code-point-at": "^1.0.0",
+                "is-fullwidth-code-point": "^1.0.0",
+                "strip-ansi": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/npm/node_modules/wrappy": {
+            "version": "1.0.2",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/write-file-atomic": {
+            "version": "2.4.3",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "graceful-fs": "^4.1.11",
+                "imurmurhash": "^0.1.4",
+                "signal-exit": "^3.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/xdg-basedir": {
+            "version": "3.0.0",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/npm/node_modules/xtend": {
+            "version": "4.0.1",
+            "inBundle": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.4"
+            }
+        },
+        "node_modules/npm/node_modules/y18n": {
+            "version": "4.0.0",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/yallist": {
+            "version": "3.0.3",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npm/node_modules/yargs": {
+            "version": "11.1.1",
+            "inBundle": true,
+            "license": "MIT",
+            "dependencies": {
+                "cliui": "^4.0.0",
+                "decamelize": "^1.1.1",
+                "find-up": "^2.1.0",
+                "get-caller-file": "^1.0.1",
+                "os-locale": "^3.1.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",
+                "yargs-parser": "^9.0.2"
+            }
+        },
+        "node_modules/npm/node_modules/yargs-parser": {
+            "version": "9.0.2",
+            "inBundle": true,
+            "license": "ISC",
+            "dependencies": {
+                "camelcase": "^4.1.0"
+            }
+        },
+        "node_modules/npm/node_modules/yargs/node_modules/y18n": {
+            "version": "3.2.1",
+            "inBundle": true,
+            "license": "ISC"
+        },
+        "node_modules/npmlog": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+            "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+            "dependencies": {
+                "are-we-there-yet": "~1.1.2",
+                "console-control-strings": "~1.1.0",
+                "gauge": "~2.7.3",
+                "set-blocking": "~2.0.0"
+            }
+        },
+        "node_modules/nth-check": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+            "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+            "dependencies": {
+                "boolbase": "~1.0.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/nwsapi": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+            "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+            "dev": true
+        },
+        "node_modules/oauth": {
+            "version": "0.9.15",
+            "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
+            "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
+        },
+        "node_modules/oauth-sign": {
+            "version": "0.9.0",
+            "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+            "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/object-assign": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+            "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object-component": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+            "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
+        },
+        "node_modules/object-copy": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+            "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+            "dependencies": {
+                "copy-descriptor": "^0.1.0",
+                "define-property": "^0.2.5",
+                "kind-of": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object-copy/node_modules/define-property": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+            "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+            "dependencies": {
+                "is-descriptor": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object-copy/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/object-copy/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object-inspect": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+            "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw=="
+        },
+        "node_modules/object-is": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz",
+            "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.5"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object-keys": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+            "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object-to-arguments": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/object-to-arguments/-/object-to-arguments-0.0.8.tgz",
+            "integrity": "sha512-BfWfuAwuhdH1bhMG5EG90WE/eckkBhBvnke8eSEkCDXoLE9Jk5JwYGTbCx1ehGwV48HvBkn62VukPBdlMUOY9w==",
+            "dependencies": {
+                "inspect-parameters-declaration": "0.0.10",
+                "magicli": "0.0.5",
+                "split-skip": "0.0.2",
+                "stringify-parameters": "0.0.4",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "object-to-arguments": "bin/cli.js"
+            }
+        },
+        "node_modules/object-to-arguments/node_modules/inspect-parameters-declaration": {
+            "version": "0.0.10",
+            "resolved": "https://registry.npmjs.org/inspect-parameters-declaration/-/inspect-parameters-declaration-0.0.10.tgz",
+            "integrity": "sha512-L8/Bvt9iDXQTZ63xY5/MAyvzz+FagR/qGh1kIXvUpsno3AAE0Z95d6QO51zrcMGaEGpwh/57idfMxTxbvRmytg==",
+            "dependencies": {
+                "magicli": "0.0.5",
+                "split-skip": "0.0.2",
+                "stringify-parameters": "0.0.4",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "inspect-parameters-declaration": "bin/cli.js"
+            }
+        },
+        "node_modules/object-to-arguments/node_modules/magicli": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
+            "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
+            "dependencies": {
+                "commander": "^2.9.0",
+                "get-stdin": "^5.0.1",
+                "inspect-function": "^0.2.1",
+                "pipe-functions": "^1.2.0"
+            }
+        },
+        "node_modules/object-visit": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+            "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+            "dependencies": {
+                "isobject": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/object.assign": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+            "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+            "dependencies": {
+                "define-properties": "^1.1.2",
+                "function-bind": "^1.1.1",
+                "has-symbols": "^1.0.0",
+                "object-keys": "^1.0.11"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object.getownpropertydescriptors": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+            "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.0-next.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/object.pick": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+            "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+            "dependencies": {
+                "isobject": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/obuf": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+            "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+            "dev": true
+        },
+        "node_modules/on-finished": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+            "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+            "dependencies": {
+                "ee-first": "1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/opentype.js": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/opentype.js/-/opentype.js-1.3.3.tgz",
+            "integrity": "sha512-/qIY/+WnKGlPIIPhbeNjynfD2PO15G9lA/xqlX2bDH+4lc3Xz5GCQ68mqxj3DdUv6AJqCeaPvuAoH8mVL0zcuA==",
+            "dependencies": {
+                "string.prototype.codepointat": "^0.2.1",
+                "tiny-inflate": "^1.0.3"
+            },
+            "bin": {
+                "ot": "bin/ot"
+            },
+            "engines": {
+                "node": ">= 8.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "is-wsl": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/optionator": {
+            "version": "0.8.3",
+            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+            "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+            "dev": true,
+            "dependencies": {
+                "deep-is": "~0.1.3",
+                "fast-levenshtein": "~2.0.6",
+                "levn": "~0.3.0",
+                "prelude-ls": "~1.1.2",
+                "type-check": "~0.3.2",
+                "word-wrap": "~1.2.3"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/orderedmap": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz",
+            "integrity": "sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "url-parse": "^1.4.3"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/os-homedir": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+            "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/osenv": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+            "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+            "dependencies": {
+                "os-homedir": "^1.0.0",
+                "os-tmpdir": "^1.0.0"
+            }
+        },
+        "node_modules/p-debounce": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-debounce/-/p-debounce-1.0.0.tgz",
+            "integrity": "sha1-y38svu/YegnrqGHhErZ1J+Yh4v0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/p-finally": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+            "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/p-limit": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+            "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+            "dependencies": {
+                "p-try": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "p-limit": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/p-retry": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
+            "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
+            "dev": true,
+            "dependencies": {
+                "retry": "^0.12.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/package-json": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+            "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+            "dependencies": {
+                "got": "^6.7.1",
+                "registry-auth-token": "^3.0.1",
+                "registry-url": "^3.0.3",
+                "semver": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pako": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+            "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+        },
+        "node_modules/parallel-transform": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+            "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+            "dev": true,
+            "dependencies": {
+                "cyclist": "^1.0.1",
+                "inherits": "^2.0.3",
+                "readable-stream": "^2.1.5"
+            }
+        },
+        "node_modules/parallel-transform/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/parent-module": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+            "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+            "dependencies": {
+                "callsites": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/parse-asn1": {
+            "version": "5.1.6",
+            "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+            "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+            "dev": true,
+            "dependencies": {
+                "asn1.js": "^5.2.0",
+                "browserify-aes": "^1.0.0",
+                "evp_bytestokey": "^1.0.0",
+                "pbkdf2": "^3.0.3",
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/parse-json": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
+            "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
+            "dependencies": {
+                "@babel/code-frame": "^7.0.0",
+                "error-ex": "^1.3.1",
+                "json-parse-better-errors": "^1.0.1",
+                "lines-and-columns": "^1.1.6"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/parse-passwd": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+            "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/parse5": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+            "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
+            "dependencies": {
+                "@types/node": "*"
+            }
+        },
+        "node_modules/parseqs": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+            "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+            "dependencies": {
+                "better-assert": "~1.0.0"
+            }
+        },
+        "node_modules/parseuri": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+            "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+            "dependencies": {
+                "better-assert": "~1.0.0"
+            }
+        },
+        "node_modules/parseurl": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+            "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/pascalcase": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+            "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/passport": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
+            "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
+            "dependencies": {
+                "passport-strategy": "1.x.x",
+                "pause": "0.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/passport-google-oauth20": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
+            "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
+            "dependencies": {
+                "passport-oauth2": "1.x.x"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/passport-local": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
+            "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
+            "dependencies": {
+                "passport-strategy": "1.x.x"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/passport-oauth2": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz",
+            "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==",
+            "dependencies": {
+                "base64url": "3.x.x",
+                "oauth": "0.9.x",
+                "passport-strategy": "1.x.x",
+                "uid2": "0.0.x",
+                "utils-merge": "1.x.x"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/passport-strategy": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
+            "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/path-browserify": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+            "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+            "dev": true
+        },
+        "node_modules/path-dirname": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+            "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
+        },
+        "node_modules/path-exists": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+            "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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="
+        },
+        "node_modules/path-key": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+            "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/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="
+        },
+        "node_modules/path-type": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+            "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pathval": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+            "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/pause": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+            "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
+        },
+        "node_modules/pbkdf2": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz",
+            "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==",
+            "dev": true,
+            "dependencies": {
+                "create-hash": "^1.1.2",
+                "create-hmac": "^1.1.4",
+                "ripemd160": "^2.0.1",
+                "safe-buffer": "^5.0.1",
+                "sha.js": "^2.4.8"
+            },
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
+        "node_modules/pdf-parse": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz",
+            "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==",
+            "dependencies": {
+                "debug": "^3.1.0",
+                "node-ensure": "^0.0.0"
+            },
+            "engines": {
+                "node": ">=6.8.1"
+            }
+        },
+        "node_modules/pdfjs": {
+            "version": "2.3.9",
+            "resolved": "https://registry.npmjs.org/pdfjs/-/pdfjs-2.3.9.tgz",
+            "integrity": "sha512-SK4xI0UbtNo9Ub1BMVgxphdL0Cy1iN9p2SxWG98JLnVe569WF8IO60K03UxlnmSV2s5P0MV1DEuZOlUslRlinA==",
+            "dependencies": {
+                "@rkusa/linebreak": "^1.0.0",
+                "opentype.js": "^1.3.3",
+                "pako": "^1.0.11",
+                "readable-stream": "^3.6.0",
+                "unorm": "^1.6.0",
+                "uuid": "^7.0.3"
+            },
+            "engines": {
+                "node": ">=7"
+            }
+        },
+        "node_modules/pdfjs-dist": {
+            "version": "2.4.456",
+            "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.4.456.tgz",
+            "integrity": "sha512-yckJEHq3F48hcp6wStEpbN9McOj328Ib09UrBlGAKxvN2k+qYPN5iq6TH6jD1C0pso7zTep+g/CKsYgdrQd5QA=="
+        },
+        "node_modules/pdfjs/node_modules/uuid": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
+            "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
+            "bin": {
+                "uuid": "dist/bin/uuid"
+            }
+        },
+        "node_modules/pend": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+            "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
+        },
+        "node_modules/performance-now": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+            "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+        },
+        "node_modules/picomatch": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+            "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+            "dev": true,
+            "engines": {
+                "node": ">=8.6"
+            }
+        },
+        "node_modules/pify": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+            "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/pinkie": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+            "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/pinkie-promise": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+            "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+            "dependencies": {
+                "pinkie": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/pipe-functions": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/pipe-functions/-/pipe-functions-1.3.0.tgz",
+            "integrity": "sha512-6Rtbp7criZRwedlvWbUYxqlqJoAlMvYHo2UcRWq79xZ54vZcaNHpVBOcWkX3ErT2aUA69tv+uiv4zKJbhD/Wgg=="
+        },
+        "node_modules/pkg-dir": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+            "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+            "dev": true,
+            "dependencies": {
+                "find-up": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/find-up": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+            "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+            "dev": true,
+            "dependencies": {
+                "locate-path": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/locate-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+            "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+            "dev": true,
+            "dependencies": {
+                "p-locate": "^2.0.0",
+                "path-exists": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/p-limit": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+            "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+            "dev": true,
+            "dependencies": {
+                "p-try": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/p-locate": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+            "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+            "dev": true,
+            "dependencies": {
+                "p-limit": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/pkg-dir/node_modules/p-try": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+            "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/please-upgrade-node": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz",
+            "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==",
+            "dependencies": {
+                "semver-compare": "^1.0.0"
+            }
+        },
+        "node_modules/plist": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/plist/-/plist-1.2.0.tgz",
+            "integrity": "sha1-CEtQk93JJQbiWfh0uNmxr7jHlZM=",
+            "dependencies": {
+                "base64-js": "0.0.8",
+                "util-deprecate": "1.0.2",
+                "xmlbuilder": "4.0.0",
+                "xmldom": "0.1.x"
+            }
+        },
+        "node_modules/plist/node_modules/base64-js": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
+            "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/pn": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+            "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+            "dev": true
+        },
+        "node_modules/popper.js": {
+            "version": "1.16.1",
+            "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+            "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
+        },
+        "node_modules/portfinder": {
+            "version": "1.0.26",
+            "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz",
+            "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==",
+            "dev": true,
+            "dependencies": {
+                "async": "^2.6.2",
+                "debug": "^3.1.1",
+                "mkdirp": "^0.5.1"
+            },
+            "engines": {
+                "node": ">= 0.12.0"
+            }
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/postcss": {
+            "version": "7.0.27",
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz",
+            "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==",
+            "dev": true,
+            "dependencies": {
+                "chalk": "^2.4.2",
+                "source-map": "^0.6.1",
+                "supports-color": "^6.1.0"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/postcss-modules-extract-imports": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+            "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+            "dev": true,
+            "dependencies": {
+                "postcss": "^7.0.5"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/postcss-modules-local-by-default": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-2.0.6.tgz",
+            "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==",
+            "dev": true,
+            "dependencies": {
+                "postcss": "^7.0.6",
+                "postcss-selector-parser": "^6.0.0",
+                "postcss-value-parser": "^3.3.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/postcss-modules-scope": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
+            "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==",
+            "dev": true,
+            "dependencies": {
+                "postcss": "^7.0.6",
+                "postcss-selector-parser": "^6.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/postcss-modules-values": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-2.0.0.tgz",
+            "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==",
+            "dev": true,
+            "dependencies": {
+                "icss-replace-symbols": "^1.1.0",
+                "postcss": "^7.0.6"
+            }
+        },
+        "node_modules/postcss-selector-parser": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz",
+            "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
+            "dev": true,
+            "dependencies": {
+                "cssesc": "^3.0.0",
+                "indexes-of": "^1.0.1",
+                "uniq": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/postcss/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/postcss/node_modules/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,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/prebuild-install": {
+            "version": "5.3.3",
+            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
+            "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
+            "dependencies": {
+                "detect-libc": "^1.0.3",
+                "expand-template": "^2.0.3",
+                "github-from-package": "0.0.0",
+                "minimist": "^1.2.0",
+                "mkdirp": "^0.5.1",
+                "napi-build-utils": "^1.0.1",
+                "node-abi": "^2.7.0",
+                "noop-logger": "^0.1.1",
+                "npmlog": "^4.0.1",
+                "pump": "^3.0.0",
+                "rc": "^1.2.7",
+                "simple-get": "^3.0.3",
+                "tar-fs": "^2.0.0",
+                "tunnel-agent": "^0.6.0",
+                "which-pm-runs": "^1.0.0"
+            },
+            "bin": {
+                "prebuild-install": "bin.js"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/prelude-ls": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+            "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/prepend-http": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+            "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/probe-image-size": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-4.1.1.tgz",
+            "integrity": "sha512-42LqKZqTLxH/UvAZ2/cKhAsR4G/Y6B7i7fI2qtQu9hRBK4YjS6gqO+QRtwTjvojUx4+/+JuOMzLoFyRecT9qRw==",
+            "dependencies": {
+                "any-promise": "^1.3.0",
+                "deepmerge": "^4.0.0",
+                "inherits": "^2.0.3",
+                "next-tick": "^1.0.0",
+                "request": "^2.83.0",
+                "stream-parser": "~0.3.1"
+            }
+        },
+        "node_modules/probe-image-size/node_modules/deepmerge": {
+            "version": "4.2.2",
+            "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+            "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/process": {
+            "version": "0.11.10",
+            "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+            "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.6.0"
+            }
+        },
+        "node_modules/process-nextick-args": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+        },
+        "node_modules/progress": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+            "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/promise": {
+            "version": "7.3.1",
+            "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+            "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+            "dependencies": {
+                "asap": "~2.0.3"
+            }
+        },
+        "node_modules/promise-inflight": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+            "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+            "dev": true
+        },
+        "node_modules/prop-types": {
+            "version": "15.7.2",
+            "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
+            "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
+            "dependencies": {
+                "loose-envify": "^1.4.0",
+                "object-assign": "^4.1.1",
+                "react-is": "^16.8.1"
+            }
+        },
+        "node_modules/prosemirror-commands": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.4.tgz",
+            "integrity": "sha512-kj4Qi+8h3EpJtZuuEDwZ9h2/QNGWDsIX/CzjmClxi9GhxWyBUMVUvIFk0mgdqHyX20lLeGmOpc0TLA5aPzgpWg==",
+            "dependencies": {
+                "prosemirror-model": "^1.0.0",
+                "prosemirror-state": "^1.0.0",
+                "prosemirror-transform": "^1.0.0"
+            }
+        },
+        "node_modules/prosemirror-dev-tools": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/prosemirror-dev-tools/-/prosemirror-dev-tools-3.0.1.tgz",
+            "integrity": "sha512-ZLMqrdIpDstBG6kP6Pt62FB7sAiLKqtW/oWvoBqlHw1p2ovNErR1/5aR1Uxrs6dgb4nPDxbu2uMKf/yI7ok7zQ==",
+            "dependencies": {
+                "@babel/runtime": "^7.0.0",
+                "@emotion/core": "^10.0.28",
+                "@emotion/styled": "^10.0.27",
+                "emotion": "^10.0.27",
+                "html": "^1.0.0",
+                "jsondiffpatch": "^0.4.1",
+                "nanoid": "^3.1.6",
+                "prop-types": "^15.7.2",
+                "prosemirror-model": ">=1.0.0",
+                "prosemirror-state": ">=1.0.0",
+                "react-dock": "^0.2.4",
+                "react-json-tree": "^0.11.2",
+                "unstated": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/prosemirror-find-replace": {
+            "version": "0.9.0",
+            "resolved": "https://registry.npmjs.org/prosemirror-find-replace/-/prosemirror-find-replace-0.9.0.tgz",
+            "integrity": "sha1-QgsENNF5xdBJD44hSNhVGpVJY4I="
+        },
+        "node_modules/prosemirror-history": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz",
+            "integrity": "sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==",
+            "dependencies": {
+                "prosemirror-state": "^1.2.2",
+                "prosemirror-transform": "^1.0.0",
+                "rope-sequence": "^1.3.0"
+            }
+        },
+        "node_modules/prosemirror-inputrules": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.2.tgz",
+            "integrity": "sha512-Ja5Z3BWestlHYGvtSGqyvxMeB8QEuBjlHM8YnKtLGUXMDp965qdDV4goV8lJb17kIWHk7e7JNj6Catuoa3302g==",
+            "dependencies": {
+                "prosemirror-state": "^1.0.0",
+                "prosemirror-transform": "^1.0.0"
+            }
+        },
+        "node_modules/prosemirror-keymap": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.4.tgz",
+            "integrity": "sha512-Al8cVUOnDFL4gcI5IDlG6xbZ0aOD/i3B17VT+1JbHWDguCgt/lBHVTHUBcKvvbSg6+q/W4Nj1Fu6bwZSca3xjg==",
+            "dependencies": {
+                "prosemirror-state": "^1.0.0",
+                "w3c-keyname": "^2.2.0"
+            }
+        },
+        "node_modules/prosemirror-model": {
+            "version": "1.10.0",
+            "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.10.0.tgz",
+            "integrity": "sha512-xTMbbO2q4abs5lJdeRvk/SrftNfZlMdvChKziTiK+OKtP8LkQI8uw39u4S5zqyflrmW3Or6+qnyFPf1p4v2u1g==",
+            "dependencies": {
+                "orderedmap": "^1.1.0"
+            }
+        },
+        "node_modules/prosemirror-schema-list": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.1.2.tgz",
+            "integrity": "sha512-dgM9PwtM4twa5WsgSYMB+J8bwjnR43DAD3L9MsR9rKm/nZR5Y85xcjB7gusVMSsbQ2NomMZF03RE6No6mTnclQ==",
+            "dependencies": {
+                "prosemirror-model": "^1.0.0",
+                "prosemirror-transform": "^1.0.0"
+            }
+        },
+        "node_modules/prosemirror-state": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.3.tgz",
+            "integrity": "sha512-PLXh2VJsIgvlgSTH6I2Yg6vk1CzPDp21DFreVpQtDMY2S6WaMmrQgDTLRcsrD8X38v8Yc873H7+ogdGzyIPn+w==",
+            "dependencies": {
+                "prosemirror-model": "^1.0.0",
+                "prosemirror-transform": "^1.0.0"
+            }
+        },
+        "node_modules/prosemirror-transform": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.2.6.tgz",
+            "integrity": "sha512-DyV6cRip8//GIHTrqBe2B7I8VjPFQZYuBuB4clpguq1SrS9lLponoBt/0XRWxETkCVsxYSvwE76X0zo6AZhwaw==",
+            "dependencies": {
+                "prosemirror-model": "^1.0.0"
+            }
+        },
+        "node_modules/prosemirror-view": {
+            "version": "1.15.0",
+            "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.15.0.tgz",
+            "integrity": "sha512-a7Q76sO/DCZr2UX2Rv1Rbw52cr9kVIz8iJOf/rq4mPN1NA3lugq2BKJgUMwlB3U4utyw3olLigqouRHM48NJyg==",
+            "dependencies": {
+                "prosemirror-model": "^1.1.0",
+                "prosemirror-state": "^1.0.0",
+                "prosemirror-transform": "^1.1.0"
+            }
+        },
+        "node_modules/proxy-addr": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+            "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+            "dependencies": {
+                "forwarded": "~0.1.2",
+                "ipaddr.js": "1.9.1"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/proxy-from-env": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+            "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+        },
+        "node_modules/prr": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+            "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+            "dev": true
+        },
+        "node_modules/pseudomap": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+            "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+        },
+        "node_modules/psl": {
+            "version": "1.8.0",
+            "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+            "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+        },
+        "node_modules/pstree.remy": {
+            "version": "1.1.7",
+            "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz",
+            "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A=="
+        },
+        "node_modules/public-encrypt": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+            "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/public-encrypt/node_modules/bn.js": {
+            "version": "4.12.0",
+            "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+            "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+            "dev": true
+        },
+        "node_modules/pug": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
+            "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
+            "dependencies": {
+                "pug-code-gen": "^2.0.2",
+                "pug-filters": "^3.1.1",
+                "pug-lexer": "^4.1.0",
+                "pug-linker": "^3.0.6",
+                "pug-load": "^2.0.12",
+                "pug-parser": "^5.0.1",
+                "pug-runtime": "^2.0.5",
+                "pug-strip-comments": "^1.0.4"
+            }
+        },
+        "node_modules/pug-attrs": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz",
+            "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==",
+            "dependencies": {
+                "constantinople": "^3.0.1",
+                "js-stringify": "^1.0.1",
+                "pug-runtime": "^2.0.5"
+            }
+        },
+        "node_modules/pug-code-gen": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
+            "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
+            "dependencies": {
+                "constantinople": "^3.1.2",
+                "doctypes": "^1.1.0",
+                "js-stringify": "^1.0.1",
+                "pug-attrs": "^2.0.4",
+                "pug-error": "^1.3.3",
+                "pug-runtime": "^2.0.5",
+                "void-elements": "^2.0.1",
+                "with": "^5.0.0"
+            }
+        },
+        "node_modules/pug-error": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.3.tgz",
+            "integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ=="
+        },
+        "node_modules/pug-filters": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
+            "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
+            "dependencies": {
+                "clean-css": "^4.1.11",
+                "constantinople": "^3.0.1",
+                "jstransformer": "1.0.0",
+                "pug-error": "^1.3.3",
+                "pug-walk": "^1.1.8",
+                "resolve": "^1.1.6",
+                "uglify-js": "^2.6.1"
+            }
+        },
+        "node_modules/pug-lexer": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz",
+            "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==",
+            "dependencies": {
+                "character-parser": "^2.1.1",
+                "is-expression": "^3.0.0",
+                "pug-error": "^1.3.3"
+            }
+        },
+        "node_modules/pug-linker": {
+            "version": "3.0.6",
+            "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
+            "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
+            "dependencies": {
+                "pug-error": "^1.3.3",
+                "pug-walk": "^1.1.8"
+            }
+        },
+        "node_modules/pug-load": {
+            "version": "2.0.12",
+            "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
+            "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
+            "dependencies": {
+                "object-assign": "^4.1.0",
+                "pug-walk": "^1.1.8"
+            }
+        },
+        "node_modules/pug-parser": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
+            "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
+            "dependencies": {
+                "pug-error": "^1.3.3",
+                "token-stream": "0.0.1"
+            }
+        },
+        "node_modules/pug-runtime": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.5.tgz",
+            "integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw=="
+        },
+        "node_modules/pug-strip-comments": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
+            "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
+            "dependencies": {
+                "pug-error": "^1.3.3"
+            }
+        },
+        "node_modules/pug-walk": {
+            "version": "1.1.8",
+            "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz",
+            "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA=="
+        },
+        "node_modules/pump": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+            "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/pumpify": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+            "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+            "dev": true,
+            "dependencies": {
+                "duplexify": "^3.6.0",
+                "inherits": "^2.0.3",
+                "pump": "^2.0.0"
+            }
+        },
+        "node_modules/pumpify/node_modules/pump": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+            "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+            "dev": true,
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/punycode": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+            "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/puppeteer": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-3.3.0.tgz",
+            "integrity": "sha512-23zNqRltZ1PPoK28uRefWJ/zKb5Jhnzbbwbpcna2o5+QMn17F0khq5s1bdH3vPlyj+J36pubccR8wiNA/VE0Vw==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "debug": "^4.1.0",
+                "extract-zip": "^2.0.0",
+                "https-proxy-agent": "^4.0.0",
+                "mime": "^2.0.3",
+                "progress": "^2.0.1",
+                "proxy-from-env": "^1.0.0",
+                "rimraf": "^3.0.2",
+                "tar-fs": "^2.0.0",
+                "unbzip2-stream": "^1.3.3",
+                "ws": "^7.2.3"
+            },
+            "engines": {
+                "node": ">=10.18.1"
+            }
+        },
+        "node_modules/puppeteer/node_modules/agent-base": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz",
+            "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==",
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/puppeteer/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/puppeteer/node_modules/https-proxy-agent": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
+            "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==",
+            "dependencies": {
+                "agent-base": "5",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/puppeteer/node_modules/mime": {
+            "version": "2.4.6",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
+            "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/pure-color": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz",
+            "integrity": "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4="
+        },
+        "node_modules/q": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+            "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+            "engines": {
+                "node": ">=0.6.0",
+                "teleport": ">=0.2.0"
+            }
+        },
+        "node_modules/qs": {
+            "version": "6.5.2",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+            "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/query-string": {
+            "version": "6.13.1",
+            "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.1.tgz",
+            "integrity": "sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA==",
+            "dependencies": {
+                "decode-uri-component": "^0.2.0",
+                "split-on-first": "^1.0.0",
+                "strict-uri-encode": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/querystring": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+            "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.4.x"
+            }
+        },
+        "node_modules/querystring-es3": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+            "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.4.x"
+            }
+        },
+        "node_modules/querystringify": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+            "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
+            "dev": true
+        },
+        "node_modules/raf-schd": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz",
+            "integrity": "sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ=="
+        },
+        "node_modules/random-bytes": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+            "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/randombytes": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+            "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "^5.1.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "randombytes": "^2.0.5",
+                "safe-buffer": "^5.1.0"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "bytes": "3.1.0",
+                "http-errors": "1.7.2",
+                "iconv-lite": "0.4.24",
+                "unpipe": "1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "loader-utils": "^1.1.0",
+                "schema-utils": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/raw-loader/node_modules/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==",
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/rc": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+            "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/rc-switch": {
+            "version": "1.9.0",
+            "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-1.9.0.tgz",
+            "integrity": "sha512-Isas+egaK6qSk64jaEw4GgPStY4umYDbT7ZY93bZF1Af+b/JEsKsJdNOU2qG3WI0Z6tXo2DDq0kJCv8Yhu0zww==",
+            "dependencies": {
+                "classnames": "^2.2.1",
+                "prop-types": "^15.5.6",
+                "react-lifecycles-compat": "^3.0.4"
+            }
+        },
+        "node_modules/react": {
+            "version": "16.13.1",
+            "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz",
+            "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1",
+                "prop-types": "^15.6.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/react-audio-waveform": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/react-audio-waveform/-/react-audio-waveform-0.0.5.tgz",
+            "integrity": "sha512-4dJwhl+LQRuywzmmjuhWT5GueT3Ai2ZhB+loVxg0sRdhplyDp96xAu10/V/+J25Cl7YqNtl2DWSxvSoI/i6l6w=="
+        },
+        "node_modules/react-autosuggest": {
+            "version": "9.4.3",
+            "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz",
+            "integrity": "sha512-wFbp5QpgFQRfw9cwKvcgLR8theikOUkv8PFsuLYqI2PUgVlx186Cz8MYt5bLxculi+jxGGUUVt+h0esaBZZouw==",
+            "dependencies": {
+                "prop-types": "^15.5.10",
+                "react-autowhatever": "^10.1.2",
+                "shallow-equal": "^1.0.0"
+            }
+        },
+        "node_modules/react-autowhatever": {
+            "version": "10.2.1",
+            "resolved": "https://registry.npmjs.org/react-autowhatever/-/react-autowhatever-10.2.1.tgz",
+            "integrity": "sha512-5gQyoETyBH6GmuW1N1J81CuoAV+Djeg66DEo03xiZOl3WOwJHBP5LisKUvCGOakjrXU4M3hcIvCIqMBYGUmqOA==",
+            "dependencies": {
+                "prop-types": "^15.5.8",
+                "react-themeable": "^1.1.0",
+                "section-iterator": "^2.0.0"
+            }
+        },
+        "node_modules/react-base16-styling": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.5.3.tgz",
+            "integrity": "sha1-OFjyTpxN2MvT9wLz901YHKKRcmk=",
+            "dependencies": {
+                "base16": "^1.0.0",
+                "lodash.curry": "^4.0.1",
+                "lodash.flow": "^3.3.0",
+                "pure-color": "^1.2.0"
+            }
+        },
+        "node_modules/react-beautiful-dnd": {
+            "version": "13.0.0",
+            "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.0.0.tgz",
+            "integrity": "sha512-87It8sN0ineoC3nBW0SbQuTFXM6bUqM62uJGY4BtTf0yzPl8/3+bHMWkgIe0Z6m8e+gJgjWxefGRVfpE3VcdEg==",
+            "dependencies": {
+                "@babel/runtime": "^7.8.4",
+                "css-box-model": "^1.2.0",
+                "memoize-one": "^5.1.1",
+                "raf-schd": "^4.0.2",
+                "react-redux": "^7.1.1",
+                "redux": "^4.0.4",
+                "use-memo-one": "^1.1.1"
+            }
+        },
+        "node_modules/react-color": {
+            "version": "2.18.1",
+            "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.18.1.tgz",
+            "integrity": "sha512-X5XpyJS6ncplZs74ak0JJoqPi+33Nzpv5RYWWxn17bslih+X7OlgmfpmGC1fNvdkK7/SGWYf1JJdn7D2n5gSuQ==",
+            "dependencies": {
+                "@icons/material": "^0.2.4",
+                "lodash": "^4.17.11",
+                "material-colors": "^1.2.1",
+                "prop-types": "^15.5.10",
+                "reactcss": "^1.2.0",
+                "tinycolor2": "^1.4.1"
+            }
+        },
+        "node_modules/react-compound-slider": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/react-compound-slider/-/react-compound-slider-2.5.0.tgz",
+            "integrity": "sha512-T84FtSI0bkQPmH5GaaHbL+2McOyIR6M5sqS80dqw/bHc5r2UKLYY64BWTbsL+XO0jlx7REuJJnZUBqo4eSRl7g==",
+            "dependencies": {
+                "@babel/runtime": "^7.7.7",
+                "d3-array": "^1.2.4",
+                "prop-types": "^15.7.2",
+                "warning": "^3.0.0"
+            }
+        },
+        "node_modules/react-datepicker": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.0.0.tgz",
+            "integrity": "sha512-Yrxan1tERAiWS0EzitpiaiXOIz0APTUtV75uWbaS+jSaKoGCR6wUN2FDwr1ACGlnEoGhR9QQ2Vq3odnWtgJsOA==",
+            "dependencies": {
+                "classnames": "^2.2.6",
+                "date-fns": "^2.0.1",
+                "prop-types": "^15.7.2",
+                "react-onclickoutside": "^6.9.0",
+                "react-popper": "^1.3.4"
+            }
+        },
+        "node_modules/react-dock": {
+            "version": "0.2.4",
+            "resolved": "https://registry.npmjs.org/react-dock/-/react-dock-0.2.4.tgz",
+            "integrity": "sha1-5yfcdVCztzEWY13LnA4E0Lev4Xw=",
+            "dependencies": {
+                "lodash.debounce": "^3.1.1",
+                "prop-types": "^15.5.8"
+            }
+        },
+        "node_modules/react-dom": {
+            "version": "16.13.1",
+            "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz",
+            "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1",
+                "prop-types": "^15.6.2",
+                "scheduler": "^0.19.1"
+            }
+        },
+        "node_modules/react-draggable": {
+            "version": "4.4.3",
+            "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
+            "integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
+            "dependencies": {
+                "classnames": "^2.2.5",
+                "prop-types": "^15.6.0"
+            }
+        },
+        "node_modules/react-event-listener": {
+            "version": "0.6.6",
+            "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz",
+            "integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==",
+            "dependencies": {
+                "@babel/runtime": "^7.2.0",
+                "prop-types": "^15.6.0",
+                "warning": "^4.0.1"
+            }
+        },
+        "node_modules/react-event-listener/node_modules/warning": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+            "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+            "dependencies": {
+                "loose-envify": "^1.0.0"
+            }
+        },
+        "node_modules/react-grid-layout": {
+            "version": "0.18.3",
+            "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-0.18.3.tgz",
+            "integrity": "sha512-lHkrk941Tk5nTwZPa9uj6ttHBT0VehSHwEhWbINBJKvM1GRaFNOefvjcuxSyuCI5JWjVUP+Qm3ARt2470AlxMA==",
+            "dependencies": {
+                "classnames": "2.x",
+                "lodash.isequal": "^4.0.0",
+                "prop-types": "^15.0.0",
+                "react-draggable": "^4.0.0",
+                "react-resizable": "^1.9.0"
+            }
+        },
+        "node_modules/react-image-lightbox-with-rotate": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/react-image-lightbox-with-rotate/-/react-image-lightbox-with-rotate-5.1.1.tgz",
+            "integrity": "sha512-5ZubUQefKSDGIiAwK4lkfmGr/bgIfNDHXqC+Fm6nbNwTVYuYOZ1RJjULOniEB4fxb3Vm0z/x0oNhi1lbP1aMtg==",
+            "dependencies": {
+                "blueimp-load-image": "^2.19.0",
+                "prop-types": "^15.6.1",
+                "react-modal": "^3.4.4"
+            }
+        },
+        "node_modules/react-input-autosize": {
+            "version": "2.2.2",
+            "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz",
+            "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==",
+            "dependencies": {
+                "prop-types": "^15.5.8"
+            }
+        },
+        "node_modules/react-is": {
+            "version": "16.13.1",
+            "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+            "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+        },
+        "node_modules/react-json-tree": {
+            "version": "0.11.2",
+            "resolved": "https://registry.npmjs.org/react-json-tree/-/react-json-tree-0.11.2.tgz",
+            "integrity": "sha512-aYhUPj1y5jR3ZQ+G3N7aL8FbTyO03iLwnVvvEikLcNFqNTyabdljo9xDftZndUBFyyyL0aK3qGO9+8EilILHUw==",
+            "dependencies": {
+                "babel-runtime": "^6.6.1",
+                "prop-types": "^15.5.8",
+                "react-base16-styling": "^0.5.1"
+            }
+        },
+        "node_modules/react-jsx-parser": {
+            "version": "1.25.1",
+            "resolved": "https://registry.npmjs.org/react-jsx-parser/-/react-jsx-parser-1.25.1.tgz",
+            "integrity": "sha512-lCHAw7iOocnPSpjfsHXZQGLyPpr9wlk3qtkVN44hZs0PwQuxcH8MWbLY+j6pqB9QSijM7qtulDLgFIYbAcqSmQ==",
+            "dependencies": {
+                "acorn": "^7.2.0",
+                "acorn-jsx": "^5.2.0",
+                "core-js": "^3.6.5"
+            }
+        },
+        "node_modules/react-jsx-parser/node_modules/acorn": {
+            "version": "7.3.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz",
+            "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==",
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/react-jsx-parser/node_modules/core-js": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz",
+            "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==",
+            "hasInstallScript": true
+        },
+        "node_modules/react-lifecycles-compat": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
+            "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
+        },
+        "node_modules/react-loading": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/react-loading/-/react-loading-2.0.3.tgz",
+            "integrity": "sha512-Vdqy79zq+bpeWJqC+xjltUjuGApyoItPgL0vgVfcJHhqwU7bAMKzysfGW/ADu6i0z0JiOCRJjo+IkFNkRNbA3A=="
+        },
+        "node_modules/react-measure": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.3.0.tgz",
+            "integrity": "sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A==",
+            "dependencies": {
+                "@babel/runtime": "^7.2.0",
+                "get-node-dimensions": "^1.2.1",
+                "prop-types": "^15.6.2",
+                "resize-observer-polyfill": "^1.5.0"
+            }
+        },
+        "node_modules/react-merge-refs": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/react-merge-refs/-/react-merge-refs-1.1.0.tgz",
+            "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ=="
+        },
+        "node_modules/react-modal": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.11.2.tgz",
+            "integrity": "sha512-o8gvvCOFaG1T7W6JUvsYjRjMVToLZgLIsi5kdhFIQCtHxDkA47LznX62j+l6YQkpXDbvQegsDyxe/+JJsFQN7w==",
+            "dependencies": {
+                "exenv": "^1.2.0",
+                "prop-types": "^15.5.10",
+                "react-lifecycles-compat": "^3.0.0",
+                "warning": "^4.0.3"
+            }
+        },
+        "node_modules/react-modal/node_modules/warning": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+            "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+            "dependencies": {
+                "loose-envify": "^1.0.0"
+            }
+        },
+        "node_modules/react-onclickoutside": {
+            "version": "6.9.0",
+            "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz",
+            "integrity": "sha512-8ltIY3bC7oGhj2nPAvWOGi+xGFybPNhJM0V1H8hY/whNcXgmDeaeoCMPPd8VatrpTsUWjb/vGzrmu6SrXVty3A=="
+        },
+        "node_modules/react-popper": {
+            "version": "1.3.7",
+            "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz",
+            "integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==",
+            "dependencies": {
+                "@babel/runtime": "^7.1.2",
+                "create-react-context": "^0.3.0",
+                "deep-equal": "^1.1.1",
+                "popper.js": "^1.14.4",
+                "prop-types": "^15.6.1",
+                "typed-styles": "^0.0.7",
+                "warning": "^4.0.2"
+            }
+        },
+        "node_modules/react-popper/node_modules/create-react-context": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz",
+            "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==",
+            "dependencies": {
+                "gud": "^1.0.0",
+                "warning": "^4.0.3"
+            }
+        },
+        "node_modules/react-popper/node_modules/warning": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+            "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+            "dependencies": {
+                "loose-envify": "^1.0.0"
+            }
+        },
+        "node_modules/react-reconciler": {
+            "version": "0.26.2",
+            "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.26.2.tgz",
+            "integrity": "sha512-nK6kgY28HwrMNwDnMui3dvm3rCFjZrcGiuwLc5COUipBK5hWHLOxMJhSnSomirqWwjPBJKV1QcbkI0VJr7Gl1Q==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1",
+                "scheduler": "^0.20.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/react-reconciler/node_modules/scheduler": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz",
+            "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1"
+            }
+        },
+        "node_modules/react-redux": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz",
+            "integrity": "sha512-EvCAZYGfOLqwV7gh849xy9/pt55rJXPwmYvI4lilPM5rUT/1NxuuN59ipdBksRVSvz0KInbPnp4IfoXJXCqiDA==",
+            "dependencies": {
+                "@babel/runtime": "^7.5.5",
+                "hoist-non-react-statics": "^3.3.0",
+                "loose-envify": "^1.4.0",
+                "prop-types": "^15.7.2",
+                "react-is": "^16.9.0"
+            }
+        },
+        "node_modules/react-resizable": {
+            "version": "1.10.1",
+            "resolved": "https://registry.npmjs.org/react-resizable/-/react-resizable-1.10.1.tgz",
+            "integrity": "sha512-Jd/bKOKx6+19NwC4/aMLRu/J9/krfxlDnElP41Oc+oLiUWs/zwV1S9yBfBZRnqAwQb6vQ/HRSk3bsSWGSgVbpw==",
+            "dependencies": {
+                "prop-types": "15.x",
+                "react-draggable": "^4.0.3"
+            }
+        },
+        "node_modules/react-resizable-rotatable-draggable": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/react-resizable-rotatable-draggable/-/react-resizable-rotatable-draggable-0.2.0.tgz",
+            "integrity": "sha512-F8TPx3z7/AcmRViySbYV3LpUWXFpHlGAmKmNcYMgPlS+h1eYFazRG3xYS8Z6e48hWY1EcCny/YNrwRNUrap8CQ==",
+            "engines": {
+                "node": ">=8",
+                "npm": ">=6"
+            }
+        },
+        "node_modules/react-reveal": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/react-reveal/-/react-reveal-1.2.2.tgz",
+            "integrity": "sha512-JCv3fAoU6Z+Lcd8U48bwzm4pMZ79qsedSXYwpwt6lJNtj/v5nKJYZZbw3yhaQPPgYePo3Y0NOCoYOq/jcsisuw==",
+            "dependencies": {
+                "prop-types": "^15.5.10"
+            }
+        },
+        "node_modules/react-select": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz",
+            "integrity": "sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g==",
+            "dependencies": {
+                "@babel/runtime": "^7.4.4",
+                "@emotion/cache": "^10.0.9",
+                "@emotion/core": "^10.0.9",
+                "@emotion/css": "^10.0.9",
+                "memoize-one": "^5.0.0",
+                "prop-types": "^15.6.0",
+                "react-input-autosize": "^2.2.2",
+                "react-transition-group": "^4.3.0"
+            }
+        },
+        "node_modules/react-select/node_modules/dom-helpers": {
+            "version": "5.1.4",
+            "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+            "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
+            "dependencies": {
+                "@babel/runtime": "^7.8.7",
+                "csstype": "^2.6.7"
+            }
+        },
+        "node_modules/react-select/node_modules/react-transition-group": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+            "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
+            "dependencies": {
+                "@babel/runtime": "^7.5.5",
+                "dom-helpers": "^5.0.1",
+                "loose-envify": "^1.4.0",
+                "prop-types": "^15.6.2"
+            }
+        },
+        "node_modules/react-table": {
+            "version": "6.11.5",
+            "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz",
+            "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==",
+            "dependencies": {
+                "@types/react-table": "^6.8.5",
+                "classnames": "^2.2.5",
+                "react-is": "^16.8.1"
+            }
+        },
+        "node_modules/react-themeable": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
+            "integrity": "sha1-fURm3ZsrX6dQWHJ4JenxUro3mg4=",
+            "dependencies": {
+                "object-assign": "^3.0.0"
+            }
+        },
+        "node_modules/react-themeable/node_modules/object-assign": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
+            "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/react-three-fiber": {
+            "version": "0.0.0-deprecated",
+            "resolved": "https://registry.npmjs.org/react-three-fiber/-/react-three-fiber-0.0.0-deprecated.tgz",
+            "integrity": "sha512-EblIqTAsIpkYeM8bZtC4lcpTE0A2zCEGipFB52RgcQq/q+0oryrk7Sxt+sqhIjUu6xMNEVywV8dr74lz5yWO6A=="
+        },
+        "node_modules/react-transition-group": {
+            "version": "2.9.0",
+            "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
+            "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
+            "dependencies": {
+                "dom-helpers": "^3.4.0",
+                "loose-envify": "^1.4.0",
+                "prop-types": "^15.6.2",
+                "react-lifecycles-compat": "^3.0.4"
+            }
+        },
+        "node_modules/react-use-measure": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.0.4.tgz",
+            "integrity": "sha512-7K2HIGaPMl3Q9ZQiEVjen3tRXl4UDda8LiTPy/QxP8dP2rl5gPBhf7mMH6MVjjRNv3loU7sNzey/ycPNnHVTxQ==",
+            "dependencies": {
+                "debounce": "^1.2.0"
+            }
+        },
+        "node_modules/reactcss": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
+            "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
+            "dependencies": {
+                "lodash": "^4.0.1"
+            }
+        },
+        "node_modules/read-pkg": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+            "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+            "dependencies": {
+                "load-json-file": "^1.0.0",
+                "normalize-package-data": "^2.3.2",
+                "path-type": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read-pkg-up": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+            "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+            "dependencies": {
+                "find-up": "^1.0.0",
+                "read-pkg": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/find-up": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+            "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+            "dependencies": {
+                "path-exists": "^2.0.0",
+                "pinkie-promise": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read-pkg-up/node_modules/path-exists": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+            "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+            "dependencies": {
+                "pinkie-promise": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read-pkg/node_modules/path-type": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+            "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "pify": "^2.0.0",
+                "pinkie-promise": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read-pkg/node_modules/pify": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+            "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/readable-stream": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/readdirp": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+            "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+            "dependencies": {
+                "graceful-fs": "^4.1.11",
+                "micromatch": "^3.1.10",
+                "readable-stream": "^2.0.2"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/readdirp/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/readline": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz",
+            "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw="
+        },
+        "node_modules/rechoir": {
+            "version": "0.6.2",
+            "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+            "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+            "dependencies": {
+                "resolve": "^1.1.6"
+            },
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/recompose": {
+            "version": "0.26.0",
+            "resolved": "https://registry.npmjs.org/recompose/-/recompose-0.26.0.tgz",
+            "integrity": "sha512-KwOu6ztO0mN5vy3+zDcc45lgnaUoaQse/a5yLVqtzTK13czSWnFGmXbQVmnoMgDkI5POd1EwIKSbjU1V7xdZog==",
+            "dependencies": {
+                "change-emitter": "^0.1.2",
+                "fbjs": "^0.8.1",
+                "hoist-non-react-statics": "^2.3.1",
+                "symbol-observable": "^1.0.4"
+            }
+        },
+        "node_modules/recompose/node_modules/hoist-non-react-statics": {
+            "version": "2.5.5",
+            "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz",
+            "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw=="
+        },
+        "node_modules/redent": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+            "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+            "dependencies": {
+                "indent-string": "^2.1.0",
+                "strip-indent": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/reduce-flatten": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
+            "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/redux": {
+            "version": "4.0.5",
+            "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
+            "integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
+            "dependencies": {
+                "loose-envify": "^1.4.0",
+                "symbol-observable": "^1.2.0"
+            }
+        },
+        "node_modules/regenerator-runtime": {
+            "version": "0.13.5",
+            "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+            "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+        },
+        "node_modules/regex-not": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+            "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+            "dependencies": {
+                "extend-shallow": "^3.0.2",
+                "safe-regex": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/regexp-clone": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
+            "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
+        },
+        "node_modules/regexp.prototype.flags": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+            "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.0-next.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/registry-auth-token": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
+            "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
+            "dependencies": {
+                "rc": "^1.1.6",
+                "safe-buffer": "^5.0.1"
+            }
+        },
+        "node_modules/registry-url": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+            "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+            "dependencies": {
+                "rc": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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="
+        },
+        "node_modules/repeat-element": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+            "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/repeat-string": {
+            "version": "1.6.1",
+            "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+            "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/repeating": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+            "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+            "dependencies": {
+                "is-finite": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/request": {
+            "version": "2.88.2",
+            "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+            "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+            "dependencies": {
+                "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.3",
+                "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.5.0",
+                "tunnel-agent": "^0.6.0",
+                "uuid": "^3.3.2"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/request-promise": {
+            "version": "4.2.5",
+            "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
+            "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
+            "dependencies": {
+                "bluebird": "^3.5.0",
+                "request-promise-core": "1.1.3",
+                "stealthy-require": "^1.1.1",
+                "tough-cookie": "^2.3.3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/request-promise-core": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
+            "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
+            "dependencies": {
+                "lodash": "^4.17.15"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/request-promise-native": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
+            "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
+            "dev": true,
+            "dependencies": {
+                "request-promise-core": "1.1.3",
+                "stealthy-require": "^1.1.1",
+                "tough-cookie": "^2.3.3"
+            },
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/request/node_modules/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==",
+            "dependencies": {
+                "asynckit": "^0.4.0",
+                "combined-stream": "^1.0.6",
+                "mime-types": "^2.1.12"
+            },
+            "engines": {
+                "node": ">= 0.12"
+            }
+        },
+        "node_modules/require_optional": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
+            "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
+            "dependencies": {
+                "resolve-from": "^2.0.0",
+                "semver": "^5.1.0"
+            }
+        },
+        "node_modules/require_optional/node_modules/resolve-from": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
+            "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/require-directory": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+            "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/require-package-name": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
+            "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk="
+        },
+        "node_modules/requires-port": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+            "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+            "dev": true
+        },
+        "node_modules/resize-observer-polyfill": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+            "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+        },
+        "node_modules/resolve": {
+            "version": "1.17.0",
+            "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
+            "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
+            "dependencies": {
+                "path-parse": "^1.0.6"
+            }
+        },
+        "node_modules/resolve-cwd": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+            "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+            "dev": true,
+            "dependencies": {
+                "resolve-from": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/resolve-cwd/node_modules/resolve-from": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+            "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/resolve-dir": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+            "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+            "dev": true,
+            "dependencies": {
+                "expand-tilde": "^2.0.0",
+                "global-modules": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/resolve-dir/node_modules/global-modules": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+            "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+            "dev": true,
+            "dependencies": {
+                "global-prefix": "^1.0.1",
+                "is-windows": "^1.0.1",
+                "resolve-dir": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/resolve-from": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+            "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/resolve-url": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+            "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
+        },
+        "node_modules/ret": {
+            "version": "0.1.15",
+            "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+            "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
+        "node_modules/retry": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+            "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+            "dev": true,
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/reveal.js": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/reveal.js/-/reveal.js-4.0.2.tgz",
+            "integrity": "sha512-LWZSUenufF1gpD7npxJ7KfoQQFKgc1D6XrLTFgKlwWNP1BQ74hT48KONFWMAw+8R/QUeaScCLCLrBVHDfFIEiw==",
+            "engines": {
+                "node": ">=10.0.0"
+            }
+        },
+        "node_modules/right-align": {
+            "version": "0.1.3",
+            "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+            "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+            "dependencies": {
+                "align-text": "^0.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/rimraf": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+            "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/ripemd160": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+            "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+            "dev": true,
+            "dependencies": {
+                "hash-base": "^3.0.0",
+                "inherits": "^2.0.1"
+            }
+        },
+        "node_modules/rope-sequence": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.2.tgz",
+            "integrity": "sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg=="
+        },
+        "node_modules/rtcpeerconnection-shim": {
+            "version": "1.2.15",
+            "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
+            "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
+            "dependencies": {
+                "sdp": "^2.6.0"
+            },
+            "engines": {
+                "node": ">=6.0.0",
+                "npm": ">=3.10.0"
+            }
+        },
+        "node_modules/run-queue": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+            "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+            "dev": true,
+            "dependencies": {
+                "aproba": "^1.1.1"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/safe-regex": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+            "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+            "dependencies": {
+                "ret": "~0.1.10"
+            }
+        },
+        "node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+        },
+        "node_modules/saslprep": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
+            "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
+            "optional": true,
+            "dependencies": {
+                "sparse-bitfield": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/sass-graph": {
+            "version": "2.2.5",
+            "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz",
+            "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==",
+            "dependencies": {
+                "glob": "^7.0.0",
+                "lodash": "^4.0.0",
+                "scss-tokenizer": "^0.2.3",
+                "yargs": "^13.3.2"
+            }
+        },
+        "node_modules/sass-loader": {
+            "version": "7.3.1",
+            "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.3.1.tgz",
+            "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==",
+            "dev": true,
+            "dependencies": {
+                "clone-deep": "^4.0.1",
+                "loader-utils": "^1.0.1",
+                "neo-async": "^2.5.0",
+                "pify": "^4.0.1",
+                "semver": "^6.3.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/sass-loader/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/sax": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+            "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+        },
+        "node_modules/saxes": {
+            "version": "3.1.11",
+            "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+            "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+            "dev": true,
+            "dependencies": {
+                "xmlchars": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/scheduler": {
+            "version": "0.19.1",
+            "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz",
+            "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==",
+            "dependencies": {
+                "loose-envify": "^1.1.0",
+                "object-assign": "^4.1.1"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/scss-loader": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/scss-loader/-/scss-loader-0.0.1.tgz",
+            "integrity": "sha1-6uAXueDzjBKlMtslwiC5Avs05nE=",
+            "dev": true
+        },
+        "node_modules/scss-tokenizer": {
+            "version": "0.2.3",
+            "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+            "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+            "dependencies": {
+                "js-base64": "^2.1.8",
+                "source-map": "^0.4.2"
+            }
+        },
+        "node_modules/scss-tokenizer/node_modules/source-map": {
+            "version": "0.4.4",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+            "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+            "dependencies": {
+                "amdefine": ">=0.0.4"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/sdp": {
+            "version": "2.12.0",
+            "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
+            "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw=="
+        },
+        "node_modules/section-iterator": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz",
+            "integrity": "sha1-v0RNev7rlK1Dw5rS+yYVFifMuio="
+        },
+        "node_modules/select-hose": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+            "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+            "dev": true
+        },
+        "node_modules/selfsigned": {
+            "version": "1.10.7",
+            "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
+            "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
+            "dev": true,
+            "dependencies": {
+                "node-forge": "0.9.0"
+            }
+        },
+        "node_modules/selfsigned/node_modules/node-forge": {
+            "version": "0.9.0",
+            "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
+            "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
+            "dev": true,
+            "engines": {
+                "node": ">= 4.5.0"
+            }
+        },
+        "node_modules/semver": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
+        "node_modules/semver-compare": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+            "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
+        },
+        "node_modules/semver-diff": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+            "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+            "dependencies": {
+                "semver": "^5.0.3"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/send": {
+            "version": "0.17.1",
+            "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+            "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/send/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/send/node_modules/debug/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/serialize-javascript": {
+            "version": "1.9.1",
+            "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz",
+            "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==",
+            "dev": true
+        },
+        "node_modules/serializr": {
+            "version": "1.5.4",
+            "resolved": "https://registry.npmjs.org/serializr/-/serializr-1.5.4.tgz",
+            "integrity": "sha512-ImLlkNfNSSv9d7Ah1j/yrPk1FHbRC1zkD7URcgx/8M1eYHGUxGf/Ig/d8ML04ifqN7QesyYKsfLYA4xjAVAR/g=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/serve-index/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/serve-index/node_modules/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,
+            "dependencies": {
+                "depd": "~1.1.2",
+                "inherits": "2.0.3",
+                "setprototypeof": "1.1.0",
+                "statuses": ">= 1.4.0 < 2"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/serve-index/node_modules/inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+            "dev": true
+        },
+        "node_modules/serve-index/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+            "dev": true
+        },
+        "node_modules/serve-index/node_modules/setprototypeof": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+            "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+            "dev": true
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "encodeurl": "~1.0.2",
+                "escape-html": "~1.0.3",
+                "parseurl": "~1.3.3",
+                "send": "0.17.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/set-blocking": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+            "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+        },
+        "node_modules/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=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/set-value": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+            "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+            "dependencies": {
+                "extend-shallow": "^2.0.1",
+                "is-extendable": "^0.1.1",
+                "is-plain-object": "^2.0.3",
+                "split-string": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/set-value/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/set-value/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/setimmediate": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+            "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+        },
+        "node_modules/setprototypeof": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+            "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "^2.0.1",
+                "safe-buffer": "^5.0.1"
+            },
+            "bin": {
+                "sha.js": "bin.js"
+            }
+        },
+        "node_modules/shallow-clone": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
+            "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
+            "dev": true,
+            "dependencies": {
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shallow-equal": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
+            "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
+        },
+        "node_modules/sharp": {
+            "version": "0.23.4",
+            "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz",
+            "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "color": "^3.1.2",
+                "detect-libc": "^1.0.3",
+                "nan": "^2.14.0",
+                "npmlog": "^4.1.2",
+                "prebuild-install": "^5.3.3",
+                "semver": "^6.3.0",
+                "simple-get": "^3.1.0",
+                "tar": "^5.0.5",
+                "tunnel-agent": "^0.6.0"
+            },
+            "engines": {
+                "node": ">=8.5.0"
+            }
+        },
+        "node_modules/sharp/node_modules/fs-minipass": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+            "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+            "dependencies": {
+                "minipass": "^3.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/sharp/node_modules/minipass": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
+            "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/sharp/node_modules/minizlib": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
+            "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
+            "dependencies": {
+                "minipass": "^3.0.0",
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/sharp/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/sharp/node_modules/tar": {
+            "version": "5.0.5",
+            "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz",
+            "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==",
+            "dependencies": {
+                "chownr": "^1.1.3",
+                "fs-minipass": "^2.0.0",
+                "minipass": "^3.0.0",
+                "minizlib": "^2.1.0",
+                "mkdirp": "^0.5.0",
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/sharp/node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        },
+        "node_modules/shebang-command": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+            "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+            "dependencies": {
+                "shebang-regex": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/shebang-regex": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+            "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/shelljs": {
+            "version": "0.8.4",
+            "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
+            "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+            "dependencies": {
+                "glob": "^7.0.0",
+                "interpret": "^1.0.0",
+                "rechoir": "^0.6.2"
+            },
+            "bin": {
+                "shjs": "bin/shjs"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/shellwords": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+            "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+            "dev": true
+        },
+        "node_modules/sift": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
+            "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
+        },
+        "node_modules/signal-exit": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+            "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
+        },
+        "node_modules/simple-assign": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz",
+            "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o="
+        },
+        "node_modules/simple-concat": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
+            "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
+        },
+        "node_modules/simple-get": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+            "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+            "dependencies": {
+                "decompress-response": "^4.2.0",
+                "once": "^1.3.1",
+                "simple-concat": "^1.0.0"
+            }
+        },
+        "node_modules/simple-swizzle": {
+            "version": "0.2.2",
+            "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+            "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+            "dependencies": {
+                "is-arrayish": "^0.3.1"
+            }
+        },
+        "node_modules/simple-swizzle/node_modules/is-arrayish": {
+            "version": "0.3.2",
+            "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+            "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+        },
+        "node_modules/slash": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+            "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/sliced": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
+            "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
+        },
+        "node_modules/snapdragon": {
+            "version": "0.8.2",
+            "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+            "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "define-property": "^1.0.0",
+                "isobject": "^3.0.0",
+                "snapdragon-util": "^3.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-node/node_modules/define-property": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+            "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+            "dependencies": {
+                "is-descriptor": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-node/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-node/node_modules/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==",
+            "dependencies": {
+                "kind-of": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-node/node_modules/is-descriptor": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+            "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+            "dependencies": {
+                "is-accessor-descriptor": "^1.0.0",
+                "is-data-descriptor": "^1.0.0",
+                "kind-of": "^6.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-util": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+            "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+            "dependencies": {
+                "kind-of": "^3.2.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon-util/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/snapdragon-util/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/snapdragon/node_modules/define-property": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+            "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+            "dependencies": {
+                "is-descriptor": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon/node_modules/extend-shallow": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+            "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+            "dependencies": {
+                "is-extendable": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/snapdragon/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/socket.io": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
+            "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
+            "dependencies": {
+                "debug": "~4.1.0",
+                "engine.io": "~3.4.0",
+                "has-binary2": "~1.0.2",
+                "socket.io-adapter": "~1.1.0",
+                "socket.io-client": "2.3.0",
+                "socket.io-parser": "~3.4.0"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/socket.io-client": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
+            "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
+            "dependencies": {
+                "backo2": "1.0.2",
+                "base64-arraybuffer": "0.1.5",
+                "component-bind": "1.0.0",
+                "component-emitter": "1.2.1",
+                "debug": "~4.1.0",
+                "engine.io-client": "~3.4.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.3.0",
+                "to-array": "0.1.4"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/component-emitter": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+            "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+        },
+        "node_modules/socket.io-client/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
+        },
+        "node_modules/socket.io-client/node_modules/socket.io-parser": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
+            "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
+            "dependencies": {
+                "component-emitter": "1.2.1",
+                "debug": "~3.1.0",
+                "isarray": "2.0.1"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/socket.io-parser/node_modules/debug": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+            "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/socket.io-client/node_modules/socket.io-parser/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/socket.io-parser": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz",
+            "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==",
+            "dependencies": {
+                "component-emitter": "1.2.1",
+                "debug": "~4.1.0",
+                "isarray": "2.0.1"
+            }
+        },
+        "node_modules/socket.io-parser/node_modules/component-emitter": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+            "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+        },
+        "node_modules/socket.io-parser/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/socket.io-parser/node_modules/isarray": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+            "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
+        },
+        "node_modules/socket.io/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/sockjs": {
+            "version": "0.3.20",
+            "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz",
+            "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==",
+            "dev": true,
+            "dependencies": {
+                "faye-websocket": "^0.10.0",
+                "uuid": "^3.4.0",
+                "websocket-driver": "0.6.5"
+            }
+        },
+        "node_modules/sockjs-client": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
+            "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/sockjs-client/node_modules/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,
+            "dependencies": {
+                "websocket-driver": ">=0.5.1"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/solr-node": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/solr-node/-/solr-node-1.2.1.tgz",
+            "integrity": "sha512-DN3+FSBgpJEgGTNddzS8tNb+ILSn5MLcsWf15G9rGxi/sROHbpcevdRSVx6s5/nz56c/5AnBTBZWak7IXWX97A==",
+            "dependencies": {
+                "@log4js-node/log4js-api": "^1.0.2",
+                "node-fetch": "^2.3.0",
+                "underscore": "^1.8.3"
+            },
+            "engines": {
+                "node": ">= 0.12.0"
+            }
+        },
+        "node_modules/solr-node/node_modules/node-fetch": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
+            "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
+            "engines": {
+                "node": "4.x || >=6.0.0"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/source-map": {
+            "version": "0.5.7",
+            "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+            "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/source-map-resolve": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+            "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+            "dependencies": {
+                "atob": "^2.1.2",
+                "decode-uri-component": "^0.2.0",
+                "resolve-url": "^0.2.1",
+                "source-map-url": "^0.4.0",
+                "urix": "^0.1.0"
+            }
+        },
+        "node_modules/source-map-support": {
+            "version": "0.5.19",
+            "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+            "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+            "dev": true,
+            "dependencies": {
+                "buffer-from": "^1.0.0",
+                "source-map": "^0.6.0"
+            }
+        },
+        "node_modules/source-map-support/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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="
+        },
+        "node_modules/sparse-bitfield": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
+            "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
+            "optional": true,
+            "dependencies": {
+                "memory-pager": "^1.0.2"
+            }
+        },
+        "node_modules/spdx-correct": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+            "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+            "dependencies": {
+                "spdx-expression-parse": "^3.0.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/spdx-exceptions": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+            "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "spdx-exceptions": "^2.1.0",
+                "spdx-license-ids": "^3.0.0"
+            }
+        },
+        "node_modules/spdx-license-ids": {
+            "version": "3.0.5",
+            "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
+            "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q=="
+        },
+        "node_modules/spdy": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+            "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+            "dev": true,
+            "dependencies": {
+                "debug": "^4.1.0",
+                "handle-thing": "^2.0.0",
+                "http-deceiver": "^1.2.7",
+                "select-hose": "^2.0.0",
+                "spdy-transport": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/spdy-transport/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dev": true,
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/spdy/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dev": true,
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/split-on-first": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
+            "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/split-skip": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/split-skip/-/split-skip-0.0.2.tgz",
+            "integrity": "sha1-2J2Iu9L3Pka1FYqjcKVhIk6A1GE="
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "extend-shallow": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/sprintf-js": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+            "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+        },
+        "node_modules/sshpk": {
+            "version": "1.16.1",
+            "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+            "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/ssri": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
+            "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "^5.1.1"
+            }
+        },
+        "node_modules/standard-error": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz",
+            "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ="
+        },
+        "node_modules/standard-http-error": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz",
+            "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=",
+            "dependencies": {
+                "standard-error": ">= 1.1.0 < 2"
+            }
+        },
+        "node_modules/static-extend": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+            "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+            "dependencies": {
+                "define-property": "^0.2.5",
+                "object-copy": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/static-extend/node_modules/define-property": {
+            "version": "0.2.5",
+            "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+            "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+            "dependencies": {
+                "is-descriptor": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/statuses": {
+            "version": "1.5.0",
+            "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+            "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/stdout-stream": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+            "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+            "dependencies": {
+                "readable-stream": "^2.0.1"
+            }
+        },
+        "node_modules/stdout-stream/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/stealthy-require": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+            "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "~2.0.1",
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/stream-browserify/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "stream-shift": "^1.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "builtin-status-codes": "^3.0.0",
+                "inherits": "^2.0.1",
+                "readable-stream": "^2.3.6",
+                "to-arraybuffer": "^1.0.0",
+                "xtend": "^4.0.0"
+            }
+        },
+        "node_modules/stream-http/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/stream-parser": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
+            "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
+            "dependencies": {
+                "debug": "2"
+            }
+        },
+        "node_modules/stream-parser/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/stream-parser/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/stream-shift": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+            "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+            "dev": true
+        },
+        "node_modules/strict-uri-encode": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
+            "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/string-width": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+            "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+            "dependencies": {
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/string.prototype.codepointat": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
+            "integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
+        },
+        "node_modules/string.prototype.trimend": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
+            "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.5"
+            }
+        },
+        "node_modules/string.prototype.trimleft": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
+            "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.5",
+                "string.prototype.trimstart": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/string.prototype.trimright": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
+            "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.5",
+                "string.prototype.trimend": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/string.prototype.trimstart": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
+            "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
+            "dependencies": {
+                "define-properties": "^1.1.3",
+                "es-abstract": "^1.17.5"
+            }
+        },
+        "node_modules/stringify-parameters": {
+            "version": "0.0.4",
+            "resolved": "https://registry.npmjs.org/stringify-parameters/-/stringify-parameters-0.0.4.tgz",
+            "integrity": "sha512-H3L90ERn5UPtkpO8eugnKcLgpIVlvTyUTrcLGm607AV5JDH6z0GymtNLr3gjGlP6I6NB/mxNX9QpY6jEQGLPdQ==",
+            "dependencies": {
+                "magicli": "0.0.5",
+                "unpack-string": "0.0.2"
+            },
+            "bin": {
+                "stringify-parameters": "bin/cli.js"
+            }
+        },
+        "node_modules/stringify-parameters/node_modules/magicli": {
+            "version": "0.0.5",
+            "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
+            "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
+            "dependencies": {
+                "commander": "^2.9.0",
+                "get-stdin": "^5.0.1",
+                "inspect-function": "^0.2.1",
+                "pipe-functions": "^1.2.0"
+            }
+        },
+        "node_modules/strip-ansi": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+            "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+            "dependencies": {
+                "ansi-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/strip-bom": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+            "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+            "dependencies": {
+                "is-utf8": "^0.2.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-eof": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+            "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-indent": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+            "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+            "dependencies": {
+                "get-stdin": "^4.0.1"
+            },
+            "bin": {
+                "strip-indent": "cli.js"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-indent/node_modules/get-stdin": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+            "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+            "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "loader-utils": "^1.1.0",
+                "schema-utils": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.12.0"
+            }
+        },
+        "node_modules/style-loader/node_modules/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,
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/styled-components": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz",
+            "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==",
+            "hasInstallScript": true,
+            "dependencies": {
+                "@babel/helper-module-imports": "^7.0.0",
+                "@babel/traverse": "^7.0.0",
+                "@emotion/is-prop-valid": "^0.8.1",
+                "@emotion/unitless": "^0.7.0",
+                "babel-plugin-styled-components": ">= 1",
+                "css-to-react-native": "^2.2.2",
+                "memoize-one": "^5.0.0",
+                "merge-anything": "^2.2.4",
+                "prop-types": "^15.5.4",
+                "react-is": "^16.6.0",
+                "stylis": "^3.5.0",
+                "stylis-rule-sheet": "^0.0.10",
+                "supports-color": "^5.5.0"
+            }
+        },
+        "node_modules/stylis": {
+            "version": "3.5.4",
+            "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
+            "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q=="
+        },
+        "node_modules/stylis-rule-sheet": {
+            "version": "0.0.10",
+            "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz",
+            "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw=="
+        },
+        "node_modules/supports-color": {
+            "version": "5.5.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/symbol-tree": {
+            "version": "3.2.4",
+            "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+            "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+            "dev": true
+        },
+        "node_modules/table-layout": {
+            "version": "0.4.5",
+            "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
+            "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
+            "dependencies": {
+                "array-back": "^2.0.0",
+                "deep-extend": "~0.6.0",
+                "lodash.padend": "^4.6.1",
+                "typical": "^2.6.1",
+                "wordwrapjs": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/tapable": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+            "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/tar": {
+            "version": "4.4.13",
+            "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+            "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "fs-minipass": "^1.2.5",
+                "minipass": "^2.8.6",
+                "minizlib": "^1.2.1",
+                "mkdirp": "^0.5.0",
+                "safe-buffer": "^5.1.2",
+                "yallist": "^3.0.3"
+            },
+            "engines": {
+                "node": ">=4.5"
+            }
+        },
+        "node_modules/tar-fs": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz",
+            "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==",
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "mkdirp-classic": "^0.5.2",
+                "pump": "^3.0.0",
+                "tar-stream": "^2.0.0"
+            }
+        },
+        "node_modules/tar-stream": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz",
+            "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==",
+            "dependencies": {
+                "bl": "^4.0.1",
+                "end-of-stream": "^1.4.1",
+                "fs-constants": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            }
+        },
+        "node_modules/temp-dir": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
+            "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/tempy": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.2.1.tgz",
+            "integrity": "sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==",
+            "dependencies": {
+                "temp-dir": "^1.0.0",
+                "unique-string": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/term-size": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+            "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+            "dependencies": {
+                "execa": "^0.7.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/terser": {
+            "version": "4.8.0",
+            "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+            "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+            "dev": true,
+            "dependencies": {
+                "commander": "^2.20.0",
+                "source-map": "~0.6.1",
+                "source-map-support": "~0.5.12"
+            },
+            "bin": {
+                "terser": "bin/terser"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin": {
+            "version": "1.4.5",
+            "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
+            "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
+            "dev": true,
+            "dependencies": {
+                "cacache": "^12.0.2",
+                "find-cache-dir": "^2.1.0",
+                "is-wsl": "^1.1.0",
+                "schema-utils": "^1.0.0",
+                "serialize-javascript": "^4.0.0",
+                "source-map": "^0.6.1",
+                "terser": "^4.1.2",
+                "webpack-sources": "^1.4.0",
+                "worker-farm": "^1.7.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/cacache": {
+            "version": "12.0.4",
+            "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+            "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+            "dev": true,
+            "dependencies": {
+                "bluebird": "^3.5.5",
+                "chownr": "^1.1.1",
+                "figgy-pudding": "^3.5.1",
+                "glob": "^7.1.4",
+                "graceful-fs": "^4.1.15",
+                "infer-owner": "^1.0.3",
+                "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.3",
+                "ssri": "^6.0.1",
+                "unique-filename": "^1.1.1",
+                "y18n": "^4.0.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/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,
+            "dependencies": {
+                "commondir": "^1.0.1",
+                "make-dir": "^2.0.0",
+                "pkg-dir": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/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,
+            "dependencies": {
+                "pify": "^4.0.1",
+                "semver": "^5.6.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/mississippi": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+            "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/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,
+            "dependencies": {
+                "find-up": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/serialize-javascript": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+            "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+            "dev": true,
+            "dependencies": {
+                "randombytes": "^2.1.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/terser-webpack-plugin/node_modules/ssri": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
+            "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
+            "dev": true,
+            "dependencies": {
+                "figgy-pudding": "^3.5.1"
+            }
+        },
+        "node_modules/terser/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/textarea-caret": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.1.0.tgz",
+            "integrity": "sha512-cXAvzO9pP5CGa6NKx0WYHl+8CHKZs8byMkt3PCJBCmq2a34YA9pO1NrQET5pzeqnBjBdToF5No4rrmkDUgQC2Q=="
+        },
+        "node_modules/three": {
+            "version": "0.127.0",
+            "resolved": "https://registry.npmjs.org/three/-/three-0.127.0.tgz",
+            "integrity": "sha512-wtgrn+mhYUbobxT7QN3GPdu3SRpSBQvwY6uOzLChWS7QE//f7paDU/+wlzbg+ngeIvBBqjBHSRuywTh8A99Jng=="
+        },
+        "node_modules/through": {
+            "version": "2.3.8",
+            "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+            "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
+        },
+        "node_modules/through2": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+            "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+            "dev": true,
+            "dependencies": {
+                "readable-stream": "~2.3.6",
+                "xtend": "~4.0.1"
+            }
+        },
+        "node_modules/through2/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/thunky": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+            "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+            "dev": true
+        },
+        "node_modules/timed-out": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+            "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/timers-browserify": {
+            "version": "2.0.12",
+            "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
+            "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
+            "dev": true,
+            "dependencies": {
+                "setimmediate": "^1.0.4"
+            },
+            "engines": {
+                "node": ">=0.6.0"
+            }
+        },
+        "node_modules/tiny-inflate": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz",
+            "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="
+        },
+        "node_modules/tiny-invariant": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
+            "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
+        },
+        "node_modules/tiny-warning": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
+            "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
+        },
+        "node_modules/tinycolor2": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+            "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/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="
+        },
+        "node_modules/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
+        },
+        "node_modules/to-fast-properties": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+            "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "kind-of": "^3.0.2"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/to-object-path/node_modules/is-buffer": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+            "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+        },
+        "node_modules/to-object-path/node_modules/kind-of": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+            "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+            "dependencies": {
+                "is-buffer": "^1.1.5"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/to-regex": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+            "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+            "dependencies": {
+                "define-property": "^2.0.2",
+                "extend-shallow": "^3.0.2",
+                "regex-not": "^1.0.2",
+                "safe-regex": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/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=",
+            "dependencies": {
+                "is-number": "^3.0.0",
+                "repeat-string": "^1.6.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/toidentifier": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+            "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/token-stream": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
+            "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+        },
+        "node_modules/touch": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+            "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+            "dependencies": {
+                "nopt": "~1.0.10"
+            },
+            "bin": {
+                "nodetouch": "bin/nodetouch.js"
+            }
+        },
+        "node_modules/touch/node_modules/nopt": {
+            "version": "1.0.10",
+            "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+            "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+            "dependencies": {
+                "abbrev": "1"
+            },
+            "bin": {
+                "nopt": "bin/nopt.js"
+            }
+        },
+        "node_modules/tough-cookie": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+            "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+            "dependencies": {
+                "psl": "^1.1.28",
+                "punycode": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/tr46": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+            "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+            "dev": true,
+            "dependencies": {
+                "punycode": "^2.1.0"
+            }
+        },
+        "node_modules/translate-google-api": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/translate-google-api/-/translate-google-api-1.0.4.tgz",
+            "integrity": "sha512-KVXmo4+64/H1vIbnzf2zNiJ2JLeEB3jrEnNRP2EFNAGNqna/5bmw/Cps3pCHu0n3BzTOoWh9u6wFvrRYdzQ6Iw==",
+            "dependencies": {
+                "axios": "^0.20.0"
+            }
+        },
+        "node_modules/translate-google-api/node_modules/axios": {
+            "version": "0.20.0",
+            "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
+            "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
+            "dependencies": {
+                "follow-redirects": "^1.10.0"
+            }
+        },
+        "node_modules/traverse-chain": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz",
+            "integrity": "sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE="
+        },
+        "node_modules/tree-kill": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+            "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+            "dev": true,
+            "bin": {
+                "tree-kill": "cli.js"
+            }
+        },
+        "node_modules/trim-newlines": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+            "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/true-case-path": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+            "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+            "dependencies": {
+                "glob": "^7.1.2"
+            }
+        },
+        "node_modules/tryit": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
+            "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics="
+        },
+        "node_modules/ts-loader": {
+            "version": "5.4.5",
+            "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-5.4.5.tgz",
+            "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==",
+            "dev": true,
+            "dependencies": {
+                "chalk": "^2.3.0",
+                "enhanced-resolve": "^4.0.0",
+                "loader-utils": "^1.0.2",
+                "micromatch": "^3.1.4",
+                "semver": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=6.11.5"
+            }
+        },
+        "node_modules/ts-node": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz",
+            "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
+            "dev": true,
+            "dependencies": {
+                "arrify": "^1.0.0",
+                "buffer-from": "^1.1.0",
+                "diff": "^3.1.0",
+                "make-error": "^1.1.1",
+                "minimist": "^1.2.0",
+                "mkdirp": "^0.5.1",
+                "source-map-support": "^0.5.6",
+                "yn": "^2.0.0"
+            },
+            "bin": {
+                "ts-node": "dist/bin.js"
+            },
+            "engines": {
+                "node": ">=4.2.0"
+            }
+        },
+        "node_modules/ts-node-dev": {
+            "version": "1.0.0-pre.49",
+            "resolved": "https://registry.npmjs.org/ts-node-dev/-/ts-node-dev-1.0.0-pre.49.tgz",
+            "integrity": "sha512-iJd4QPPOaCAByl/WuEdmDX8xDR2GmoWYu6aKvGudGUcfP1sJRjpaHb7oFDuvBspQF1xhxUdbjfHuvEtZPwKZFQ==",
+            "dev": true,
+            "dependencies": {
+                "chokidar": "^3.4.0",
+                "dateformat": "~1.0.4-1.2.3",
+                "dynamic-dedupe": "^0.3.0",
+                "minimist": "^1.2.5",
+                "mkdirp": "^1.0.4",
+                "node-notifier": "^5.4.0",
+                "resolve": "^1.0.0",
+                "rimraf": "^2.6.1",
+                "source-map-support": "^0.5.12",
+                "tree-kill": "^1.2.2",
+                "ts-node": "^8.10.2",
+                "tsconfig": "^7.0.0"
+            },
+            "bin": {
+                "ts-node-dev": "bin/ts-node-dev",
+                "tsnd": "bin/ts-node-dev"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/anymatch": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+            "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+            "dev": true,
+            "dependencies": {
+                "normalize-path": "^3.0.0",
+                "picomatch": "^2.0.4"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/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,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/braces": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+            "dev": true,
+            "dependencies": {
+                "fill-range": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/chokidar": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz",
+            "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==",
+            "dev": true,
+            "dependencies": {
+                "anymatch": "~3.1.1",
+                "braces": "~3.0.2",
+                "glob-parent": "~5.1.0",
+                "is-binary-path": "~2.1.0",
+                "is-glob": "~4.0.1",
+                "normalize-path": "~3.0.0",
+                "readdirp": "~3.4.0"
+            },
+            "engines": {
+                "node": ">= 8.10.0"
+            },
+            "optionalDependencies": {
+                "fsevents": "~2.1.2"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/diff": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+            "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.3.1"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/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,
+            "dependencies": {
+                "to-regex-range": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/glob-parent": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+            "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+            "dev": true,
+            "dependencies": {
+                "is-glob": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/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,
+            "dependencies": {
+                "binary-extensions": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/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,
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/mkdirp": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+            "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+            "dev": true,
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/readdirp": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz",
+            "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==",
+            "dev": true,
+            "dependencies": {
+                "picomatch": "^2.2.1"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/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,
+            "dependencies": {
+                "is-number": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/ts-node": {
+            "version": "8.10.2",
+            "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz",
+            "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==",
+            "dev": true,
+            "dependencies": {
+                "arg": "^4.1.0",
+                "diff": "^4.0.1",
+                "make-error": "^1.1.1",
+                "source-map-support": "^0.5.17",
+                "yn": "3.1.1"
+            },
+            "bin": {
+                "ts-node": "dist/bin.js",
+                "ts-node-script": "dist/bin-script.js",
+                "ts-node-transpile-only": "dist/bin-transpile.js",
+                "ts-script": "dist/bin-script-deprecated.js"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/ts-node-dev/node_modules/yn": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+            "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/ts-node/node_modules/arrify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+            "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/tsconfig": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
+            "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
+            "dev": true,
+            "dependencies": {
+                "@types/strip-bom": "^3.0.0",
+                "@types/strip-json-comments": "0.0.30",
+                "strip-bom": "^3.0.0",
+                "strip-json-comments": "^2.0.0"
+            }
+        },
+        "node_modules/tsconfig/node_modules/strip-bom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+            "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/tslib": {
+            "version": "1.11.1",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
+            "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
+            "dev": true
+        },
+        "node_modules/tslint": {
+            "version": "5.20.1",
+            "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz",
+            "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
+            "dev": true,
+            "dependencies": {
+                "@babel/code-frame": "^7.0.0",
+                "builtin-modules": "^1.1.1",
+                "chalk": "^2.3.0",
+                "commander": "^2.12.1",
+                "diff": "^4.0.1",
+                "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"
+            },
+            "bin": {
+                "tslint": "bin/tslint"
+            },
+            "engines": {
+                "node": ">=4.8.0"
+            }
+        },
+        "node_modules/tslint-loader": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/tslint-loader/-/tslint-loader-3.6.0.tgz",
+            "integrity": "sha512-Me9Qf/87BOfCY8uJJw+J7VMF4U8WiMXKLhKKKugMydF0xMhMOt9wo2mjYTNhwbF9H7SHh8PAIwRG8roisTNekQ==",
+            "dev": true,
+            "dependencies": {
+                "loader-utils": "^1.0.2",
+                "mkdirp": "^0.5.1",
+                "object-assign": "^4.1.1",
+                "rimraf": "^2.4.4",
+                "semver": "^5.3.0"
+            }
+        },
+        "node_modules/tslint-loader/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/tslint/node_modules/diff": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+            "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.3.1"
+            }
+        },
+        "node_modules/tsscmp": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
+            "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==",
+            "engines": {
+                "node": ">=0.6.x"
+            }
+        },
+        "node_modules/tsutils": {
+            "version": "2.29.0",
+            "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+            "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+            "dev": true,
+            "dependencies": {
+                "tslib": "^1.8.1"
+            }
+        },
+        "node_modules/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
+        },
+        "node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/tweetnacl": {
+            "version": "0.14.5",
+            "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+            "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+        },
+        "node_modules/type": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+            "dev": true
+        },
+        "node_modules/type-check": {
+            "version": "0.3.2",
+            "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+            "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "~1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/type-detect": {
+            "version": "4.0.8",
+            "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+            "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/type-is": {
+            "version": "1.6.18",
+            "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+            "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+            "dependencies": {
+                "media-typer": "0.3.0",
+                "mime-types": "~2.1.24"
+            },
+            "engines": {
+                "node": ">= 0.6"
+            }
+        },
+        "node_modules/typed-styles": {
+            "version": "0.0.7",
+            "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
+            "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
+        },
+        "node_modules/typedarray": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+            "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+        },
+        "node_modules/typescript": {
+            "version": "3.9.9",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.9.tgz",
+            "integrity": "sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==",
+            "dev": true,
+            "bin": {
+                "tsc": "bin/tsc",
+                "tsserver": "bin/tsserver"
+            },
+            "engines": {
+                "node": ">=4.2.0"
+            }
+        },
+        "node_modules/typescript-collections": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/typescript-collections/-/typescript-collections-1.3.3.tgz",
+            "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ=="
+        },
+        "node_modules/typescript-language-server": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-0.4.0.tgz",
+            "integrity": "sha512-K8jNOmDFn+QfrCh8ujby2pGDs5rpjYZQn+zvQnf42rxG4IHbfw5CHoMvbGkWPK/J5Gw8/l5K3i03kVZC2IBElg==",
+            "dependencies": {
+                "command-exists": "1.2.6",
+                "commander": "^2.11.0",
+                "fs-extra": "^7.0.0",
+                "p-debounce": "^1.0.0",
+                "tempy": "^0.2.1",
+                "vscode-languageserver": "^5.3.0-next",
+                "vscode-uri": "^1.0.5"
+            },
+            "bin": {
+                "typescript-language-server": "lib/cli.js"
+            }
+        },
+        "node_modules/typescript-language-server/node_modules/fs-extra": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+            "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "jsonfile": "^4.0.0",
+                "universalify": "^0.1.0"
+            },
+            "engines": {
+                "node": ">=6 <7 || >=8"
+            }
+        },
+        "node_modules/typescript-language-server/node_modules/jsonfile": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+            "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+            "dependencies": {
+                "graceful-fs": "^4.1.6"
+            }
+        },
+        "node_modules/typical": {
+            "version": "2.6.1",
+            "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+            "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0="
+        },
+        "node_modules/ua-parser-js": {
+            "version": "0.7.21",
+            "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
+            "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==",
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/uglify-js": {
+            "version": "2.8.29",
+            "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+            "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+            "dependencies": {
+                "source-map": "~0.5.1",
+                "yargs": "~3.10.0"
+            },
+            "bin": {
+                "uglifyjs": "bin/uglifyjs"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            },
+            "optionalDependencies": {
+                "uglify-to-browserify": "~1.0.0"
+            }
+        },
+        "node_modules/uglify-js/node_modules/camelcase": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+            "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/uglify-js/node_modules/cliui": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+            "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+            "dependencies": {
+                "center-align": "^0.1.1",
+                "right-align": "^0.1.1",
+                "wordwrap": "0.0.2"
+            }
+        },
+        "node_modules/uglify-js/node_modules/yargs": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+            "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+            "dependencies": {
+                "camelcase": "^1.0.2",
+                "cliui": "^2.1.0",
+                "decamelize": "^1.0.0",
+                "window-size": "0.1.0"
+            }
+        },
+        "node_modules/uglify-to-browserify": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+            "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+            "optional": true
+        },
+        "node_modules/uid-safe": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
+            "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+            "dependencies": {
+                "random-bytes": "~1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/uid2": {
+            "version": "0.0.3",
+            "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
+            "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
+        },
+        "node_modules/unbzip2-stream": {
+            "version": "1.4.3",
+            "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+            "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+            "dependencies": {
+                "buffer": "^5.2.1",
+                "through": "^2.3.8"
+            }
+        },
+        "node_modules/undefsafe": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
+            "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
+            "dependencies": {
+                "debug": "^2.2.0"
+            }
+        },
+        "node_modules/undefsafe/node_modules/debug": {
+            "version": "2.6.9",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+            "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+            "dependencies": {
+                "ms": "2.0.0"
+            }
+        },
+        "node_modules/undefsafe/node_modules/ms": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+            "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "node_modules/underscore": {
+            "version": "1.10.2",
+            "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz",
+            "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg=="
+        },
+        "node_modules/unicode-trie": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz",
+            "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=",
+            "dependencies": {
+                "pako": "^0.2.5",
+                "tiny-inflate": "^1.0.0"
+            }
+        },
+        "node_modules/unicode-trie/node_modules/pako": {
+            "version": "0.2.9",
+            "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+            "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU="
+        },
+        "node_modules/union-value": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+            "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+            "dependencies": {
+                "arr-union": "^3.1.0",
+                "get-value": "^2.0.6",
+                "is-extendable": "^0.1.1",
+                "set-value": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/union-value/node_modules/is-extendable": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+            "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/uniq": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+            "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+            "dev": true
+        },
+        "node_modules/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,
+            "dependencies": {
+                "unique-slug": "^2.0.0"
+            }
+        },
+        "node_modules/unique-slug": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+            "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+            "dev": true,
+            "dependencies": {
+                "imurmurhash": "^0.1.4"
+            }
+        },
+        "node_modules/unique-string": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+            "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+            "dependencies": {
+                "crypto-random-string": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/universalify": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+            "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+            "engines": {
+                "node": ">= 4.0.0"
+            }
+        },
+        "node_modules/unorm": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
+            "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/unpack-string": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz",
+            "integrity": "sha1-MC7PCCOLATm9Q0pNf9Z83zPKJ10="
+        },
+        "node_modules/unpipe": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+            "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/unset-value": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+            "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+            "dependencies": {
+                "has-value": "^0.3.1",
+                "isobject": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/unset-value/node_modules/has-value": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+            "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+            "dependencies": {
+                "get-value": "^2.0.3",
+                "has-values": "^0.1.4",
+                "isobject": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+            "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+            "dependencies": {
+                "isarray": "1.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/unset-value/node_modules/has-values": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+            "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/unstated": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/unstated/-/unstated-2.1.1.tgz",
+            "integrity": "sha512-fORlTWMZxq7NuMJDxyIrrYIZKN7wEWYQ9SiaJfIRcSpsowr6Ph/JIfK2tgtXLW614JfPG/t5q9eEIhXRCf55xg==",
+            "dependencies": {
+                "create-react-context": "^0.1.5"
+            }
+        },
+        "node_modules/unstated/node_modules/create-react-context": {
+            "version": "0.1.6",
+            "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.1.6.tgz",
+            "integrity": "sha512-eCnYYEUEc5i32LHwpE/W7NlddOB9oHwsPaWtWzYtflNkkwa3IfindIcoXdVWs12zCbwaMCavKNu84EXogVIWHw=="
+        },
+        "node_modules/unzip-response": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+            "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/upath": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+            "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+            "engines": {
+                "node": ">=4",
+                "yarn": "*"
+            }
+        },
+        "node_modules/update-notifier": {
+            "version": "2.5.0",
+            "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
+            "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
+            "dependencies": {
+                "boxen": "^1.2.1",
+                "chalk": "^2.0.1",
+                "configstore": "^3.0.0",
+                "import-lazy": "^2.1.0",
+                "is-ci": "^1.0.10",
+                "is-installed-globally": "^0.1.0",
+                "is-npm": "^1.0.0",
+                "latest-version": "^3.0.0",
+                "semver-diff": "^2.0.0",
+                "xdg-basedir": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "punycode": "^2.1.0"
+            }
+        },
+        "node_modules/urix": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+            "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
+        },
+        "node_modules/url": {
+            "version": "0.11.0",
+            "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+            "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+            "dev": true,
+            "dependencies": {
+                "punycode": "1.3.2",
+                "querystring": "0.2.0"
+            }
+        },
+        "node_modules/url-loader": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz",
+            "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==",
+            "dependencies": {
+                "loader-utils": "^1.1.0",
+                "mime": "^2.0.3",
+                "schema-utils": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 6.9.0"
+            }
+        },
+        "node_modules/url-loader/node_modules/mime": {
+            "version": "2.4.4",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
+            "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/url-loader/node_modules/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==",
+            "dependencies": {
+                "ajv": "^6.1.0",
+                "ajv-errors": "^1.0.0",
+                "ajv-keywords": "^3.1.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "querystringify": "^2.1.1",
+                "requires-port": "^1.0.0"
+            }
+        },
+        "node_modules/url-parse-lax": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+            "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+            "dependencies": {
+                "prepend-http": "^1.0.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/url-template": {
+            "version": "2.0.8",
+            "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+            "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE="
+        },
+        "node_modules/url/node_modules/punycode": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+            "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+            "dev": true
+        },
+        "node_modules/use": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+            "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/use-asset": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/use-asset/-/use-asset-1.0.4.tgz",
+            "integrity": "sha512-7/hqDrWa0iMnCoET9W1T07EmD4Eg/Wmoj/X8TGBc++ECRK4m5yTsjP4O6s0yagbxfqIOuUkIxe2/sA+VR2GxZA==",
+            "dependencies": {
+                "fast-deep-equal": "^3.1.3"
+            }
+        },
+        "node_modules/use-asset/node_modules/fast-deep-equal": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+            "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+        },
+        "node_modules/use-memo-one": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.1.tgz",
+            "integrity": "sha512-oFfsyun+bP7RX8X2AskHNTxu+R3QdE/RC5IefMbqptmACAA/gfol1KDD5KRzPsGMa62sWxGZw+Ui43u6x4ddoQ=="
+        },
+        "node_modules/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,
+            "dependencies": {
+                "inherits": "2.0.3"
+            }
+        },
+        "node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+        },
+        "node_modules/util/node_modules/inherits": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+            "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+            "dev": true
+        },
+        "node_modules/utility-types": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
+            "integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==",
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/utils-merge": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+            "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/uuid": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+            "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+            "bin": {
+                "uuid": "bin/uuid"
+            }
+        },
+        "node_modules/v8-compile-cache": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
+            "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
+            "dev": true
+        },
+        "node_modules/valid-url": {
+            "version": "1.0.9",
+            "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
+            "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA="
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "spdx-correct": "^3.0.0",
+                "spdx-expression-parse": "^3.0.0"
+            }
+        },
+        "node_modules/validator": {
+            "version": "10.11.0",
+            "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
+            "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==",
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/vary": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+            "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+            "engines": {
+                "node": ">= 0.8"
+            }
+        },
+        "node_modules/verror": {
+            "version": "1.10.0",
+            "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+            "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+            "engines": [
+                "node >=0.6.0"
+            ],
+            "dependencies": {
+                "assert-plus": "^1.0.0",
+                "core-util-is": "1.0.2",
+                "extsprintf": "^1.2.0"
+            }
+        },
+        "node_modules/vm-browserify": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+            "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+            "dev": true
+        },
+        "node_modules/void-elements": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+            "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/vscode-jsonrpc": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz",
+            "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A==",
+            "engines": {
+                "node": ">=8.0.0 || >=10.0.0"
+            }
+        },
+        "node_modules/vscode-languageserver": {
+            "version": "5.3.0-next.10",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.3.0-next.10.tgz",
+            "integrity": "sha512-QL7Fe1FT6PdLtVzwJeZ78pTic4eZbzLRy7yAQgPb9xalqqgZESR0+yDZPwJrM3E7PzOmwHBceYcJR54eQZ7Kng==",
+            "dependencies": {
+                "vscode-languageserver-protocol": "^3.15.0-next.8",
+                "vscode-textbuffer": "^1.0.0"
+            },
+            "bin": {
+                "installServerIntoExtension": "bin/installServerIntoExtension"
+            }
+        },
+        "node_modules/vscode-languageserver-protocol": {
+            "version": "3.15.3",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz",
+            "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==",
+            "dependencies": {
+                "vscode-jsonrpc": "^5.0.1",
+                "vscode-languageserver-types": "3.15.1"
+            }
+        },
+        "node_modules/vscode-languageserver-types": {
+            "version": "3.15.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
+            "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
+        },
+        "node_modules/vscode-textbuffer": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/vscode-textbuffer/-/vscode-textbuffer-1.0.0.tgz",
+            "integrity": "sha512-zPaHo4urgpwsm+PrJWfNakolRpryNja18SUip/qIIsfhuEqEIPEXMxHOlFPjvDC4JgTaimkncNW7UMXRJTY6ow=="
+        },
+        "node_modules/vscode-uri": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
+            "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ=="
+        },
+        "node_modules/vue-template-compiler": {
+            "version": "2.6.11",
+            "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
+            "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==",
+            "dependencies": {
+                "de-indent": "^1.0.2",
+                "he": "^1.1.0"
+            }
+        },
+        "node_modules/w3c-hr-time": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+            "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+            "dev": true,
+            "dependencies": {
+                "browser-process-hrtime": "^1.0.0"
+            }
+        },
+        "node_modules/w3c-keyname": {
+            "version": "2.2.4",
+            "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
+            "integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw=="
+        },
+        "node_modules/w3c-xmlserializer": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+            "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+            "dev": true,
+            "dependencies": {
+                "domexception": "^1.0.1",
+                "webidl-conversions": "^4.0.2",
+                "xml-name-validator": "^3.0.0"
+            }
+        },
+        "node_modules/walkdir": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz",
+            "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==",
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/warning": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+            "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+            "dependencies": {
+                "loose-envify": "^1.0.0"
+            }
+        },
+        "node_modules/watchpack": {
+            "version": "1.7.5",
+            "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
+            "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
+            "dev": true,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "neo-async": "^2.5.0"
+            },
+            "optionalDependencies": {
+                "chokidar": "^3.4.1",
+                "watchpack-chokidar2": "^2.0.1"
+            }
+        },
+        "node_modules/watchpack-chokidar2": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz",
+            "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "chokidar": "^2.1.8"
+            }
+        },
+        "node_modules/watchpack/node_modules/anymatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
+            "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "normalize-path": "^3.0.0",
+                "picomatch": "^2.0.4"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/watchpack/node_modules/binary-extensions": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+            "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+            "dev": true,
+            "optional": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/watchpack/node_modules/braces": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "fill-range": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/watchpack/node_modules/chokidar": {
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
+            "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "anymatch": "~3.1.1",
+                "braces": "~3.0.2",
+                "fsevents": "~2.3.1",
+                "glob-parent": "~5.1.0",
+                "is-binary-path": "~2.1.0",
+                "is-glob": "~4.0.1",
+                "normalize-path": "~3.0.0",
+                "readdirp": "~3.5.0"
+            },
+            "engines": {
+                "node": ">= 8.10.0"
+            }
+        },
+        "node_modules/watchpack/node_modules/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,
+            "optional": true,
+            "dependencies": {
+                "to-regex-range": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/watchpack/node_modules/fsevents": {
+            "version": "2.3.2",
+            "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+            "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+            }
+        },
+        "node_modules/watchpack/node_modules/glob-parent": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "is-glob": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/watchpack/node_modules/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,
+            "optional": true,
+            "dependencies": {
+                "binary-extensions": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/watchpack/node_modules/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,
+            "optional": true,
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/watchpack/node_modules/readdirp": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+            "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+            "dev": true,
+            "optional": true,
+            "dependencies": {
+                "picomatch": "^2.2.1"
+            },
+            "engines": {
+                "node": ">=8.10.0"
+            }
+        },
+        "node_modules/watchpack/node_modules/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,
+            "optional": true,
+            "dependencies": {
+                "is-number": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/wbuf": {
+            "version": "1.7.3",
+            "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+            "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+            "dev": true,
+            "dependencies": {
+                "minimalistic-assert": "^1.0.0"
+            }
+        },
+        "node_modules/web-request": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/web-request/-/web-request-1.0.7.tgz",
+            "integrity": "sha1-twxCs81FV3noLbaIYlOySR8r1Wk=",
+            "dependencies": {
+                "request": "^2.69.0"
+            }
+        },
+        "node_modules/webidl-conversions": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+            "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+            "dev": true
+        },
+        "node_modules/webpack": {
+            "version": "4.46.0",
+            "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",
+            "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==",
+            "dev": true,
+            "dependencies": {
+                "@webassemblyjs/ast": "1.9.0",
+                "@webassemblyjs/helper-module-context": "1.9.0",
+                "@webassemblyjs/wasm-edit": "1.9.0",
+                "@webassemblyjs/wasm-parser": "1.9.0",
+                "acorn": "^6.4.1",
+                "ajv": "^6.10.2",
+                "ajv-keywords": "^3.4.1",
+                "chrome-trace-event": "^1.0.2",
+                "enhanced-resolve": "^4.5.0",
+                "eslint-scope": "^4.0.3",
+                "json-parse-better-errors": "^1.0.2",
+                "loader-runner": "^2.4.0",
+                "loader-utils": "^1.2.3",
+                "memory-fs": "^0.4.1",
+                "micromatch": "^3.1.10",
+                "mkdirp": "^0.5.3",
+                "neo-async": "^2.6.1",
+                "node-libs-browser": "^2.2.1",
+                "schema-utils": "^1.0.0",
+                "tapable": "^1.1.3",
+                "terser-webpack-plugin": "^1.4.3",
+                "watchpack": "^1.7.4",
+                "webpack-sources": "^1.4.1"
+            },
+            "bin": {
+                "webpack": "bin/webpack.js"
+            },
+            "engines": {
+                "node": ">=6.11.5"
+            }
+        },
+        "node_modules/webpack-cli": {
+            "version": "3.3.12",
+            "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz",
+            "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==",
+            "dev": true,
+            "dependencies": {
+                "chalk": "^2.4.2",
+                "cross-spawn": "^6.0.5",
+                "enhanced-resolve": "^4.1.1",
+                "findup-sync": "^3.0.0",
+                "global-modules": "^2.0.0",
+                "import-local": "^2.0.0",
+                "interpret": "^1.4.0",
+                "loader-utils": "^1.4.0",
+                "supports-color": "^6.1.0",
+                "v8-compile-cache": "^2.1.1",
+                "yargs": "^13.3.2"
+            },
+            "bin": {
+                "webpack-cli": "bin/cli.js"
+            },
+            "engines": {
+                "node": ">=6.11.5"
+            }
+        },
+        "node_modules/webpack-cli/node_modules/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,
+            "dependencies": {
+                "nice-try": "^1.0.4",
+                "path-key": "^2.0.1",
+                "semver": "^5.5.0",
+                "shebang-command": "^1.2.0",
+                "which": "^1.2.9"
+            },
+            "engines": {
+                "node": ">=4.8"
+            }
+        },
+        "node_modules/webpack-cli/node_modules/interpret": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
+            "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.10"
+            }
+        },
+        "node_modules/webpack-cli/node_modules/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,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/webpack-dev-middleware": {
+            "version": "3.7.3",
+            "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
+            "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==",
+            "dev": true,
+            "dependencies": {
+                "memory-fs": "^0.4.1",
+                "mime": "^2.4.4",
+                "mkdirp": "^0.5.1",
+                "range-parser": "^1.2.1",
+                "webpack-log": "^2.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/webpack-dev-middleware/node_modules/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=",
+            "dev": true,
+            "dependencies": {
+                "errno": "^0.1.3",
+                "readable-stream": "^2.0.1"
+            }
+        },
+        "node_modules/webpack-dev-middleware/node_modules/mime": {
+            "version": "2.5.2",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz",
+            "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==",
+            "dev": true,
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/webpack-dev-middleware/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/webpack-dev-middleware/node_modules/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,
+            "dependencies": {
+                "ansi-colors": "^3.0.0",
+                "uuid": "^3.3.2"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/webpack-dev-server": {
+            "version": "3.11.0",
+            "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz",
+            "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==",
+            "dev": true,
+            "dependencies": {
+                "ansi-html": "0.0.7",
+                "bonjour": "^3.5.0",
+                "chokidar": "^2.1.8",
+                "compression": "^1.7.4",
+                "connect-history-api-fallback": "^1.6.0",
+                "debug": "^4.1.1",
+                "del": "^4.1.1",
+                "express": "^4.17.1",
+                "html-entities": "^1.3.1",
+                "http-proxy-middleware": "0.19.1",
+                "import-local": "^2.0.0",
+                "internal-ip": "^4.3.0",
+                "ip": "^1.1.5",
+                "is-absolute-url": "^3.0.3",
+                "killable": "^1.0.1",
+                "loglevel": "^1.6.8",
+                "opn": "^5.5.0",
+                "p-retry": "^3.0.1",
+                "portfinder": "^1.0.26",
+                "schema-utils": "^1.0.0",
+                "selfsigned": "^1.10.7",
+                "semver": "^6.3.0",
+                "serve-index": "^1.9.1",
+                "sockjs": "0.3.20",
+                "sockjs-client": "1.4.0",
+                "spdy": "^4.0.2",
+                "strip-ansi": "^3.0.1",
+                "supports-color": "^6.1.0",
+                "url": "^0.11.0",
+                "webpack-dev-middleware": "^3.7.2",
+                "webpack-log": "^2.0.0",
+                "ws": "^6.2.1",
+                "yargs": "^13.3.2"
+            },
+            "bin": {
+                "webpack-dev-server": "bin/webpack-dev-server.js"
+            },
+            "engines": {
+                "node": ">= 6.11.5"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/debug": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+            "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+            "dev": true,
+            "dependencies": {
+                "ms": "^2.1.1"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/semver": {
+            "version": "6.3.0",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver.js"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/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,
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/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,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/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,
+            "dependencies": {
+                "ansi-colors": "^3.0.0",
+                "uuid": "^3.3.2"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/webpack-dev-server/node_modules/ws": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+            "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+            "dev": true,
+            "dependencies": {
+                "async-limiter": "~1.0.0"
+            }
+        },
+        "node_modules/webpack-hot-middleware": {
+            "version": "2.25.0",
+            "resolved": "https://registry.npmjs.org/webpack-hot-middleware/-/webpack-hot-middleware-2.25.0.tgz",
+            "integrity": "sha512-xs5dPOrGPCzuRXNi8F6rwhawWvQQkeli5Ro48PRuQh8pYPCPmNnltP9itiUPT4xI8oW+y0m59lyyeQk54s5VgA==",
+            "dev": true,
+            "dependencies": {
+                "ansi-html": "0.0.7",
+                "html-entities": "^1.2.0",
+                "querystring": "^0.2.0",
+                "strip-ansi": "^3.0.0"
+            }
+        },
+        "node_modules/webpack-hot-middleware/node_modules/ansi-regex": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+            "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/webpack-hot-middleware/node_modules/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,
+            "dependencies": {
+                "ansi-regex": "^2.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/webpack-log": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz",
+            "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==",
+            "dev": true,
+            "dependencies": {
+                "chalk": "^2.1.0",
+                "log-symbols": "^2.1.0",
+                "loglevelnext": "^1.0.1",
+                "uuid": "^3.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/webpack-sources": {
+            "version": "1.4.3",
+            "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+            "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+            "dev": true,
+            "dependencies": {
+                "source-list-map": "^2.0.0",
+                "source-map": "~0.6.1"
+            }
+        },
+        "node_modules/webpack-sources/node_modules/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,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/webpack/node_modules/acorn": {
+            "version": "6.4.2",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+            "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+            "dev": true,
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/webpack/node_modules/enhanced-resolve": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
+            "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==",
+            "dev": true,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "memory-fs": "^0.5.0",
+                "tapable": "^1.0.0"
+            },
+            "engines": {
+                "node": ">=6.9.0"
+            }
+        },
+        "node_modules/webpack/node_modules/enhanced-resolve/node_modules/memory-fs": {
+            "version": "0.5.0",
+            "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+            "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+            "dev": true,
+            "dependencies": {
+                "errno": "^0.1.3",
+                "readable-stream": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=4.3.0 <5.0.0 || >=5.10"
+            }
+        },
+        "node_modules/webpack/node_modules/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=",
+            "dev": true,
+            "dependencies": {
+                "errno": "^0.1.3",
+                "readable-stream": "^2.0.1"
+            }
+        },
+        "node_modules/webpack/node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "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"
+            }
+        },
+        "node_modules/webrtc-adapter": {
+            "version": "7.6.3",
+            "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.6.3.tgz",
+            "integrity": "sha512-DCMiS6cy29PknSuBz779twM6/VsPdoQNAU/I/q4VCEVSlCQ88xiwqGD5/osVO6UMyXCnTBiOl8kd+1cJi6Pkig==",
+            "dependencies": {
+                "rtcpeerconnection-shim": "^1.2.15",
+                "sdp": "^2.12.0"
+            },
+            "engines": {
+                "node": ">=6.0.0",
+                "npm": ">=3.10.0"
+            }
+        },
+        "node_modules/websocket-driver": {
+            "version": "0.6.5",
+            "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz",
+            "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=",
+            "dev": true,
+            "dependencies": {
+                "websocket-extensions": ">=0.1.1"
+            },
+            "engines": {
+                "node": ">=0.6.0"
+            }
+        },
+        "node_modules/websocket-extensions": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+            "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/whatwg-encoding": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+            "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+            "dev": true,
+            "dependencies": {
+                "iconv-lite": "0.4.24"
+            }
+        },
+        "node_modules/whatwg-fetch": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
+            "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
+        },
+        "node_modules/whatwg-mimetype": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+            "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+            "dev": true
+        },
+        "node_modules/whatwg-url": {
+            "version": "7.1.0",
+            "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+            "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+            "dev": true,
+            "dependencies": {
+                "lodash.sortby": "^4.7.0",
+                "tr46": "^1.0.1",
+                "webidl-conversions": "^4.0.2"
+            }
+        },
+        "node_modules/which": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+            "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+            "dependencies": {
+                "isexe": "^2.0.0"
+            },
+            "bin": {
+                "which": "bin/which"
+            }
+        },
+        "node_modules/which-module": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+            "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
+        },
+        "node_modules/which-pm-runs": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+            "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
+        },
+        "node_modules/wide-align": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+            "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+            "dependencies": {
+                "string-width": "^1.0.2 || 2"
+            }
+        },
+        "node_modules/widest-line": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
+            "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
+            "dependencies": {
+                "string-width": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/wikijs": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/wikijs/-/wikijs-6.0.1.tgz",
+            "integrity": "sha512-67ZtXyVPspYM5/B5ci0NIwvPJyG23HPk33QQLgLbCcORQ6N0I3Mhxd/KsPRh3xyly87KDs/bh1xuIG6PVTCKGw==",
+            "dependencies": {
+                "cheerio": "^1.0.0-rc.3",
+                "cross-fetch": "^3.0.2",
+                "infobox-parser": "3.3.1"
+            },
+            "engines": {
+                "node": ">=0.10.4"
+            }
+        },
+        "node_modules/window-size": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+            "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/with": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
+            "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+            "dependencies": {
+                "acorn": "^3.1.0",
+                "acorn-globals": "^3.0.0"
+            }
+        },
+        "node_modules/word-wrap": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/words-to-numbers": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/words-to-numbers/-/words-to-numbers-1.5.1.tgz",
+            "integrity": "sha512-uvz7zSCKmmA7o5f5zp4Z5l24RQhy6HSNu10URhNxQWv1I82RsFaZX3qD07RLFUMJsCV38oAuaca13AvhO+9yGw==",
+            "dependencies": {
+                "babel-runtime": "6.x.x",
+                "clj-fuzzy": "^0.3.2",
+                "its-set": "^1.1.5"
+            }
+        },
+        "node_modules/wordwrap": {
+            "version": "0.0.2",
+            "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+            "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/wordwrapjs": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
+            "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
+            "dependencies": {
+                "reduce-flatten": "^1.0.1",
+                "typical": "^2.6.1"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/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,
+            "dependencies": {
+                "errno": "~0.1.7"
+            }
+        },
+        "node_modules/worker-rpc": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz",
+            "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==",
+            "dev": true,
+            "dependencies": {
+                "microevent.ts": "~0.1.1"
+            }
+        },
+        "node_modules/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==",
+            "dependencies": {
+                "ansi-styles": "^3.2.0",
+                "string-width": "^3.0.0",
+                "strip-ansi": "^5.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/wrap-ansi/node_modules/ansi-regex": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+            "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/wrap-ansi/node_modules/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==",
+            "dependencies": {
+                "emoji-regex": "^7.0.1",
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/wrap-ansi/node_modules/strip-ansi": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+            "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+            "dependencies": {
+                "ansi-regex": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+        },
+        "node_modules/write-file-atomic": {
+            "version": "2.4.3",
+            "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
+            "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+            "dependencies": {
+                "graceful-fs": "^4.1.11",
+                "imurmurhash": "^0.1.4",
+                "signal-exit": "^3.0.2"
+            }
+        },
+        "node_modules/ws": {
+            "version": "7.2.5",
+            "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz",
+            "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA==",
+            "engines": {
+                "node": ">=8.3.0"
+            }
+        },
+        "node_modules/xdg-basedir": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+            "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/xml-name-validator": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+            "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+            "dev": true
+        },
+        "node_modules/xmlbuilder": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.0.0.tgz",
+            "integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=",
+            "dependencies": {
+                "lodash": "^3.5.0"
+            },
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/xmlbuilder/node_modules/lodash": {
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+            "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
+        },
+        "node_modules/xmlchars": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+            "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+            "dev": true
+        },
+        "node_modules/xmldom": {
+            "version": "0.1.31",
+            "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+            "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
+            "engines": {
+                "node": ">=0.1"
+            }
+        },
+        "node_modules/xmlhttprequest-ssl": {
+            "version": "1.5.5",
+            "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+            "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=",
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/xoauth2": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-1.2.0.tgz",
+            "integrity": "sha1-8u76wRRyyXHqO8RuVU60sSMhRuU="
+        },
+        "node_modules/xregexp": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz",
+            "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==",
+            "dependencies": {
+                "@babel/runtime-corejs3": "^7.8.3"
+            }
+        },
+        "node_modules/xtend": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+            "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.4"
+            }
+        },
+        "node_modules/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=="
+        },
+        "node_modules/yallist": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+            "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+        },
+        "node_modules/yaml": {
+            "version": "1.10.0",
+            "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
+            "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==",
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/yargs": {
+            "version": "13.3.2",
+            "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+            "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+            "dependencies": {
+                "cliui": "^5.0.0",
+                "find-up": "^3.0.0",
+                "get-caller-file": "^2.0.1",
+                "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.2"
+            }
+        },
+        "node_modules/yargs-parser": {
+            "version": "13.1.2",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+            "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+            "dependencies": {
+                "camelcase": "^5.0.0",
+                "decamelize": "^1.2.0"
+            }
+        },
+        "node_modules/yargs-unparser": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+            "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+            "dependencies": {
+                "flat": "^4.1.0",
+                "lodash": "^4.17.15",
+                "yargs": "^13.3.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/yargs/node_modules/ansi-regex": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+            "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/yargs/node_modules/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==",
+            "dependencies": {
+                "emoji-regex": "^7.0.1",
+                "is-fullwidth-code-point": "^2.0.0",
+                "strip-ansi": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/yargs/node_modules/strip-ansi": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+            "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+            "dependencies": {
+                "ansi-regex": "^4.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/yauzl": {
+            "version": "2.10.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+            "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+            "dependencies": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer": "~1.1.0"
+            }
+        },
+        "node_modules/yeast": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+            "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
+        },
+        "node_modules/yn": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
+            "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/zip-stream": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz",
+            "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==",
+            "dependencies": {
+                "archiver-utils": "^2.1.0",
+                "compress-commons": "^2.1.1",
+                "readable-stream": "^3.4.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/zustand": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.4.1.tgz",
+            "integrity": "sha512-Kb91vSjy5vwBQ/PQ1a5GE6naS3gCxCgpkujT9zqZSO85+gnvmzgqraMW3ao1I0jR4PwHBXtLTf26r9j7EXoUiQ=="
+        }
+    },
     "dependencies": {
         "@babel/code-frame": {
             "version": "7.8.3",
@@ -3688,22 +26608,22 @@
                             "bundled": true,
                             "optional": true
                         },
-                        "string-width": {
-                            "version": "1.0.2",
+                        "string_decoder": {
+                            "version": "1.1.1",
                             "bundled": true,
                             "optional": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "safe-buffer": "~5.1.0"
                             }
                         },
-                        "string_decoder": {
-                            "version": "1.1.1",
+                        "string-width": {
+                            "version": "1.0.2",
                             "bundled": true,
                             "optional": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "code-point-at": "^1.0.0",
+                                "is-fullwidth-code-point": "^1.0.0",
+                                "strip-ansi": "^3.0.0"
                             }
                         },
                         "strip-ansi": {
@@ -5800,8 +28720,8 @@
             "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
         },
         "equation-editor-react": {
-            "version": "github:bobzel/equation-editor-react#75915e852b4b36a6a4cd3e1cbc80598da6b65227",
-            "from": "github:bobzel/equation-editor-react#useLocally",
+            "version": "git+ssh://git@github.com/bobzel/equation-editor-react.git#75915e852b4b36a6a4cd3e1cbc80598da6b65227",
+            "from": "equation-editor-react@github:bobzel/equation-editor-react#useLocally",
             "requires": {
                 "jquery": "^3.4.1",
                 "mathquill": "^0.10.1-a"
@@ -7700,8 +30620,8 @@
             },
             "dependencies": {
                 "image-size": {
-                    "version": "github:netroy/image-size#da2c863807a3e9602617bdd357b0de3ab4a064c1",
-                    "from": "github:netroy/image-size#da2c863807a3e9602617bdd357b0de3ab4a064c1"
+                    "version": "git+ssh://git@github.com/netroy/image-size.git#da2c863807a3e9602617bdd357b0de3ab4a064c1",
+                    "from": "image-size@github:netroy/image-size#da2c863807a3e9602617bdd357b0de3ab4a064c1"
                 },
                 "isarray": {
                     "version": "0.0.1",
@@ -10125,7 +33045,6 @@
             "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.5.tgz",
             "integrity": "sha512-CDwa3FJd0XJpKDbWCST484H+mCNjF26dPrU+xnREW+upR0UODjMEfXPl3bxWuAwZIX6c2ASg1plLO7jP8ehWeA==",
             "requires": {
-                "JSONStream": "^1.3.5",
                 "abbrev": "~1.1.1",
                 "ansicolors": "~0.3.2",
                 "ansistyles": "~0.1.3",
@@ -10166,6 +33085,7 @@
                 "init-package-json": "^1.10.3",
                 "is-cidr": "^3.0.0",
                 "json-parse-better-errors": "^1.0.2",
+                "JSONStream": "^1.3.5",
                 "lazy-property": "~1.0.0",
                 "libcipm": "^4.0.7",
                 "libnpm": "^3.0.1",
@@ -10250,14 +33170,6 @@
                 "write-file-atomic": "^2.4.3"
             },
             "dependencies": {
-                "JSONStream": {
-                    "version": "1.3.5",
-                    "bundled": true,
-                    "requires": {
-                        "jsonparse": "^1.2.0",
-                        "through": ">=2.2.7 <3"
-                    }
-                },
                 "abbrev": {
                     "version": "1.1.1",
                     "bundled": true
@@ -11504,6 +34416,14 @@
                     "version": "1.3.1",
                     "bundled": true
                 },
+                "JSONStream": {
+                    "version": "1.3.5",
+                    "bundled": true,
+                    "requires": {
+                        "jsonparse": "^1.2.0",
+                        "through": ">=2.2.7 <3"
+                    }
+                },
                 "jsprim": {
                     "version": "1.4.1",
                     "bundled": true,
@@ -12080,9 +35000,9 @@
                     "version": "4.0.4",
                     "bundled": true,
                     "requires": {
-                        "JSONStream": "^1.3.4",
                         "bluebird": "^3.5.1",
                         "figgy-pudding": "^3.4.1",
+                        "JSONStream": "^1.3.4",
                         "lru-cache": "^5.1.1",
                         "make-fetch-happen": "^5.0.0",
                         "npm-package-arg": "^6.1.0",
@@ -12828,6 +35748,19 @@
                     "version": "2.0.0",
                     "bundled": true
                 },
+                "string_decoder": {
+                    "version": "1.3.0",
+                    "bundled": true,
+                    "requires": {
+                        "safe-buffer": "~5.2.0"
+                    },
+                    "dependencies": {
+                        "safe-buffer": {
+                            "version": "5.2.0",
+                            "bundled": true
+                        }
+                    }
+                },
                 "string-width": {
                     "version": "2.1.1",
                     "bundled": true,
@@ -12853,19 +35786,6 @@
                         }
                     }
                 },
-                "string_decoder": {
-                    "version": "1.3.0",
-                    "bundled": true,
-                    "requires": {
-                        "safe-buffer": "~5.2.0"
-                    },
-                    "dependencies": {
-                        "safe-buffer": {
-                            "version": "5.2.0",
-                            "bundled": true
-                        }
-                    }
-                },
                 "stringify-package": {
                     "version": "1.0.1",
                     "bundled": true
@@ -15379,21 +38299,6 @@
                 "tough-cookie": "^2.3.3"
             }
         },
-        "require-directory": {
-            "version": "2.1.1",
-            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-            "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
-        },
-        "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=="
-        },
-        "require-package-name": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
-            "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk="
-        },
         "require_optional": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
@@ -15410,6 +38315,21 @@
                 }
             }
         },
+        "require-directory": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+            "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+        },
+        "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=="
+        },
+        "require-package-name": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
+            "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk="
+        },
         "requires-port": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -16692,6 +39612,14 @@
             "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
             "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
         },
+        "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"
+            }
+        },
         "string-width": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -16744,14 +39672,6 @@
                 "es-abstract": "^1.17.5"
             }
         },
-        "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"
-            }
-        },
         "stringify-parameters": {
             "version": "0.0.4",
             "resolved": "https://registry.npmjs.org/stringify-parameters/-/stringify-parameters-0.0.4.tgz",
diff --git a/src/client/ClientRecommender.scss b/src/client/ClientRecommender.scss
index 3f9102f15..178c7fdab 100644
--- a/src/client/ClientRecommender.scss
+++ b/src/client/ClientRecommender.scss
@@ -1,4 +1,4 @@
-// @import "/views/globalCssVariables.scss";
+// @import "/views/global/globalCssVariables.scss";
 
 .space{
     border: 1px dashed blue;
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 24682cbd0..0c4d266d4 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -30,7 +30,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie
 import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
 import { ContextMenu } from "../views/ContextMenu";
 import { ContextMenuProps } from "../views/ContextMenuItem";
-import { DFLT_IMAGE_NATIVE_DIM } from "../views/globalCssVariables.scss";
+import { DFLT_IMAGE_NATIVE_DIM } from "../views/global/globalCssVariables.scss";
 import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, InkingStroke } from "../views/InkingStroke";
 import { AudioBox } from "../views/nodes/AudioBox";
 import { ColorBox } from "../views/nodes/ColorBox";
diff --git a/src/client/util/CaptureManager.scss b/src/client/util/CaptureManager.scss
index 71539ee1e..a5024247e 100644
--- a/src/client/util/CaptureManager.scss
+++ b/src/client/util/CaptureManager.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
 
 .capture-interface {
     //background-color: whitesmoke !important;
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index d8c2f913e..e0e6024d2 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -9,7 +9,7 @@ import { ScriptField } from "../../fields/ScriptField";
 import { Cast, NumCast, ScriptCast, StrCast } from "../../fields/Types";
 import { emptyFunction, returnTrue } from "../../Utils";
 import { Docs, DocUtils } from "../documents/Documents";
-import * as globalCssVariables from "../views/globalCssVariables.scss";
+import * as globalCssVariables from "../views/global/globalCssVariables.scss";
 import { UndoManager } from "./UndoManager";
 import { SnappingManager } from "./SnappingManager";
 import { DocumentView } from "../views/nodes/DocumentView";
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index d8342ea56..c9db94419 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
 
 .settings-interface {
     //background-color: whitesmoke !important;
@@ -264,7 +264,7 @@
         //margin-top: 4px;
 
         &:hover {
-            background: $main-accent;
+            background: $medium-gray;
         }
     }
 
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index a275901be..8670b1747 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -1,4 +1,4 @@
-@import "./globalCssVariables";
+@import "./global/globalCssVariables";
 
 
 .antimodeMenu-cont {
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index b514de5f2..2590e34c6 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -1,10 +1,10 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 
 .contextMenu-cont {
     position: absolute;
     display: flex;
     z-index: $contextMenu-zindex;
-    box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+    box-shadow: $medium-gray 0.2vw 0.2vw 0.4vw;
     flex-direction: column;
     background: whitesmoke;
     padding-top: 10px;
@@ -14,17 +14,17 @@
 }
 
 // .contextMenu-item:first-child {
-//     background: $intermediate-color;
-//     color: $light-color;
+//     background: $medium-gray;
+//     color: $white;
 // }
 
 // .contextMenu-item:first-child::placeholder {
-//     color: $light-color;
+//     color: $white;
 // }
 
 // .contextMenu-item:first-child:hover {
-//     background: $intermediate-color;
-//     color: $light-color;
+//     background: $medium-gray;
+//     color: $white;
 // }
 
 .contextMenu-subMenu-cont {
@@ -94,7 +94,7 @@
 .contextMenu-item:hover {
     border-width: .11px;
     border-style: none;
-    border-color: $intermediate-color; //  rgb(187, 186, 186);
+    border-color: $medium-gray; //  rgb(187, 186, 186);
     border-bottom-style: solid;
     border-top-style: solid;
 
@@ -122,7 +122,7 @@
     transition: all .1s;
     border-width: .11px;
     border-style: none;
-    border-color: $intermediate-color; //  rgb(187, 186, 186);
+    border-color: $medium-gray; //  rgb(187, 186, 186);
     // padding: 10px 0px 10px 0px;
     white-space: nowrap;
     font-size: 13px;
diff --git a/src/client/views/DocumentButtonBar.scss b/src/client/views/DocumentButtonBar.scss
index 09ae14016..e816c52a3 100644
--- a/src/client/views/DocumentButtonBar.scss
+++ b/src/client/views/DocumentButtonBar.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 
 $linkGap : 3px;
 
@@ -7,13 +7,13 @@ $linkGap : 3px;
 }
 
 .documentButtonBar-linkButton-empty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
 
 .documentButtonBar-linkButton-nonempty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
@@ -26,7 +26,7 @@ $linkGap : 3px;
     opacity: 0.9;
     pointer-events: auto;
     background-color: $dark-color;
-    color: $light-color;
+    color: $white;
     text-transform: uppercase;
     letter-spacing: 2px;
     font-size: 75%;
@@ -37,7 +37,7 @@ $linkGap : 3px;
     align-items: center;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
         cursor: pointer;
     }
@@ -69,7 +69,7 @@ $linkGap : 3px;
     transition: 0.2s ease all;
 
     &:hover {
-        background-color: $main-accent;
+        background-color: $medium-gray;
     }
 }
 
diff --git a/src/client/views/DocumentDecorations.scss b/src/client/views/DocumentDecorations.scss
index db2d56aa8..47a8326bb 100644
--- a/src/client/views/DocumentDecorations.scss
+++ b/src/client/views/DocumentDecorations.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 
 $linkGap : 3px;
 
@@ -49,7 +49,7 @@ $linkGap : 3px;
     .documentDecorations-bottomResizer,
     .documentDecorations-rightResizer {
         pointer-events: auto;
-        background: $alt-accent;
+        background: $medium-gray;
         opacity: 0.1;
         &:hover {
             opacity: 1;
@@ -251,13 +251,13 @@ $linkGap : 3px;
 }
 
 .linkButton-empty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
 
 .linkButton-nonempty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
@@ -271,7 +271,7 @@ $linkGap : 3px;
     flex-direction: row;
     z-index: 998;
     position: absolute;
-    background: $alt-accent;
+    background: $medium-gray;
 }
 
 .linkButtonWrapper {
@@ -303,7 +303,7 @@ $linkGap : 3px;
     opacity: 0.9;
     pointer-events: auto;
     background-color: $dark-color;
-    color: $light-color;
+    color: $white;
     text-transform: uppercase;
     letter-spacing: 2px;
     font-size: 75%;
@@ -314,7 +314,7 @@ $linkGap : 3px;
     align-items: center;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
         cursor: pointer;
     }
@@ -344,12 +344,12 @@ $linkGap : 3px;
     opacity: 0.9;
     font-size: 14;
     background-color: $dark-color;
-    color: $light-color;
+    color: $white;
     text-align: center;
     cursor: pointer;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
     }
 }
@@ -365,7 +365,7 @@ $linkGap : 3px;
     width: max-content;
     font-family: $sans-serif;
     font-size: 12px;
-    background-color: $light-color-secondary;
+    background-color: $light-gray;
     padding: 2px 12px;
     list-style: none;
 
diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss
index b1ad4868c..c8e64b5c4 100644
--- a/src/client/views/Main.scss
+++ b/src/client/views/Main.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 @import "nodeModuleOverrides";
 
 :root {
@@ -54,7 +54,7 @@ button {
     background: black;
     outline: none;
     border: 0px;
-    color: $light-color;
+    color: $white;
     text-transform: uppercase;
     letter-spacing: 2px;
     font-size: 75%;
@@ -63,7 +63,7 @@ button {
 }
 
 button:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 3f04a0f3a..d76458460 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 @import "nodeModuleOverrides";
 
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eeb1fc95..f34851b00 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -40,7 +40,7 @@ import { ContextMenu } from './ContextMenu';
 import { DictationOverlay } from './DictationOverlay';
 import { DocumentDecorations } from './DocumentDecorations';
 import { GestureOverlay } from './GestureOverlay';
-import { MENU_PANEL_WIDTH, SEARCH_PANEL_HEIGHT } from './globalCssVariables.scss';
+import { MENU_PANEL_WIDTH, SEARCH_PANEL_HEIGHT } from './global/globalCssVariables.scss';
 import { KeyManager } from './GlobalKeyHandler';
 import { InkStrokeProperties } from './InkStrokeProperties';
 import { LightboxView } from './LightboxView';
@@ -180,8 +180,8 @@ export class MainView extends React.Component {
             const targClass = targets[0].className.toString();
             if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
-                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                        thing.className === "collectionSchema-header-menuOptions"));
+                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+                    thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
             }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 29d2bfcb7..4ef7763be 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 
 $linkGap : 3px;
 
@@ -7,13 +7,13 @@ $linkGap : 3px;
 }
 
 .propertiesButtons-linkButton-empty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
 
 .propertiesButtons-linkButton-nonempty:hover {
-    background: $main-accent;
+    background: $medium-gray;
     transform: scale(1.05);
     cursor: pointer;
 }
@@ -24,7 +24,7 @@ $linkGap : 3px;
     width: 29px;
     border-radius: 6px;
     pointer-events: auto;
-    background-color: #121721;
+    background-color: $dark-color;
     color: #fcfbf7;
     text-transform: uppercase;
     letter-spacing: 2px;
@@ -38,18 +38,18 @@ $linkGap : 3px;
     margin-left: 4px;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
         cursor: pointer;
     }
 }
 .propertiesButtons-linkButton-empty.toggle-on {
     background-color: white;
-    color: black;
+    color: $dark-color;
 }
 .propertiesButtons-linkButton-empty.toggle-hover {
     background-color: gray;
-    color: black;
+    color: $dark-color;
 }
 .propertiesButtons-linkButton-empty.toggle-off {
     color: white;
@@ -111,7 +111,7 @@ $linkGap : 3px;
     margin-left: 4px;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
         cursor: pointer;
     }
diff --git a/src/client/views/TemplateMenu.scss b/src/client/views/TemplateMenu.scss
index bbed8cd96..f81cbdaab 100644
--- a/src/client/views/TemplateMenu.scss
+++ b/src/client/views/TemplateMenu.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 .templating-menu {
     position: absolute;
     pointer-events: auto;
@@ -24,7 +24,7 @@
     cursor: pointer;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
     }
 }
@@ -32,7 +32,7 @@
 .template-list {
     font-family: $sans-serif;
     font-size: 12px;
-    background-color: $light-color-secondary;
+    background-color: $light-gray;
     padding: 2px 12px;
     list-style: none;
     position: relative;
diff --git a/src/client/views/animationtimeline/Keyframe.scss b/src/client/views/animationtimeline/Keyframe.scss
index 84c8de287..38eb103c6 100644
--- a/src/client/views/animationtimeline/Keyframe.scss
+++ b/src/client/views/animationtimeline/Keyframe.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
 
 
 $timelineColor: #9acedf;
@@ -15,11 +15,11 @@ $timelineDark: #77a1aa;
         height: 200px;
         top: 50%;
         position: relative;
-        background-color: $light-color;
+        background-color: $white;
 
         .menutable {
             tr:nth-child(odd) {
-                background-color: $light-color-secondary;
+                background-color: $light-gray;
             }
         }
     }
@@ -67,7 +67,7 @@ $timelineDark: #77a1aa;
         height: 100%;
         position: absolute;
         pointer-events: none;
-        background: linear-gradient(to left, $timelineColor 10%, $light-color);
+        background: linear-gradient(to left, $timelineColor 10%, $white);
     }
 
     .fadeRight {
@@ -75,7 +75,7 @@ $timelineDark: #77a1aa;
         height: 100%;
         position: absolute;
         pointer-events: none;
-        background: linear-gradient(to right, $timelineColor 10%, $light-color);
+        background: linear-gradient(to right, $timelineColor 10%, $white);
     }
 
     .divider {
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index e84022366..82b0218bf 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -1,7 +1,7 @@
 import * as React from "react";
 import "./Keyframe.scss";
 import "./Timeline.scss";
-import "../globalCssVariables.scss";
+import "../global/globalCssVariables.scss";
 import { observer } from "mobx-react";
 import { observable, reaction, action, IReactionDisposer, observe, computed, runInAction, trace } from "mobx";
 import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../fields/Doc";
diff --git a/src/client/views/animationtimeline/Timeline.scss b/src/client/views/animationtimeline/Timeline.scss
index f90249771..d82eb85bf 100644
--- a/src/client/views/animationtimeline/Timeline.scss
+++ b/src/client/views/animationtimeline/Timeline.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
 
 $timelineColor: #9acedf;
 $timelineDark: #77a1aa;
@@ -161,7 +161,7 @@ $timelineDark: #77a1aa;
     width: 100%;
     height: 300px;
     position: absolute;
-    background-color: $light-color-secondary;
+    background-color: $light-gray;
     border-bottom: 2px solid $timelineDark;
     transition: transform 500ms ease;
 
diff --git a/src/client/views/animationtimeline/TimelineMenu.scss b/src/client/views/animationtimeline/TimelineMenu.scss
index 7ee0a43d5..935f04aba 100644
--- a/src/client/views/animationtimeline/TimelineMenu.scss
+++ b/src/client/views/animationtimeline/TimelineMenu.scss
@@ -1,10 +1,10 @@
-@import "./../globalCssVariables.scss"; 
+@import "./../global/globalCssVariables.scss"; 
 
 
 .timeline-menu-container{
     position: absolute;
     display: flex;
-    box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
+    box-shadow: $medium-gray 0.2vw 0.2vw 0.4vw;
     flex-direction: column;
     background: whitesmoke;
     z-index: 10000;
@@ -79,7 +79,7 @@
     .timeline-menu-item:hover {
         border-width: .11px;
         border-style: none;
-        border-color: $intermediate-color;
+        border-color: $medium-gray;
         border-bottom-style: solid;
         border-top-style: solid;
         background: $darker-alt-accent; 
diff --git a/src/client/views/animationtimeline/TimelineOverview.scss b/src/client/views/animationtimeline/TimelineOverview.scss
index 283163ea7..c8d96c399 100644
--- a/src/client/views/animationtimeline/TimelineOverview.scss
+++ b/src/client/views/animationtimeline/TimelineOverview.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
 
 $timelineColor: #9acedf;
 $timelineDark: #77a1aa;
diff --git a/src/client/views/animationtimeline/Track.scss b/src/client/views/animationtimeline/Track.scss
index aec587a79..6d6d1620f 100644
--- a/src/client/views/animationtimeline/Track.scss
+++ b/src/client/views/animationtimeline/Track.scss
@@ -1,4 +1,4 @@
-@import "./../globalCssVariables.scss";
+@import "./../global/globalCssVariables.scss";
 
 .track-container {
 
@@ -6,7 +6,7 @@
         .inner {
             top: 0px;
             width: calc(100%);
-            background-color: $light-color;
+            background-color: $white;
             border: 1px solid $dark-color;
             position: relative;
             z-index: 100;
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index f4736eb29..6d5dc9b18 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -1,4 +1,4 @@
-@import "../../views/globalCssVariables.scss";
+@import "../../views/global/globalCssVariables.scss";
 
 
 .lm_title {
@@ -110,7 +110,7 @@
     }
 
     .flexlayout__splitter {
-        background-color: black;
+        background-color: $dark-color;
     }
 
     .flexlayout__splitter:hover {
@@ -179,7 +179,7 @@
         position: absolute;
         box-sizing: border-box;
         background-color: #222;
-        color: black;
+        color: $dark-color;
     }
 
     .flexlayout__tab_button {
@@ -268,7 +268,7 @@
     }
 
     .flexlayout__tab_header_outer {
-        background-color: black;
+        background-color: $dark-color;
         position: absolute;
         left: 0;
         right: 0;
@@ -332,28 +332,28 @@
     }
 
     .flexlayout__border_top {
-        background-color: black;
+        background-color: $dark-color;
         border-bottom: 1px solid #ddd;
         box-sizing: border-box;
         overflow: hidden;
     }
 
     .flexlayout__border_bottom {
-        background-color: black;
+        background-color: $dark-color;
         border-top: 1px solid #333;
         box-sizing: border-box;
         overflow: hidden;
     }
 
     .flexlayout__border_left {
-        background-color: black;
+        background-color: $dark-color;
         border-right: 1px solid #333;
         box-sizing: border-box;
         overflow: hidden;
     }
 
     .flexlayout__border_right {
-        background-color: black;
+        background-color: $dark-color;
         border-left: 1px solid #333;
         box-sizing: border-box;
         overflow: hidden;
diff --git a/src/client/views/collections/CollectionLinearView.scss b/src/client/views/collections/CollectionLinearView.scss
index ca72b98a5..632ce4417 100644
--- a/src/client/views/collections/CollectionLinearView.scss
+++ b/src/client/views/collections/CollectionLinearView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 @import "../_nodeModuleOverrides";
 
 .collectionLinearView-outer {
@@ -13,7 +13,7 @@
 
         >span {
             background: $dark-color;
-            color: $light-color;
+            color: $white;
             border-radius: 18px;
             margin-right: 6px;
             cursor: pointer;
@@ -64,7 +64,7 @@
             margin-top: "auto";
             margin-bottom: "auto";
             background: $dark-color;
-            color: $light-color;
+            color: $white;
             display: inline-block;
             border-radius: 18px;
             font-size: 12.5px;
@@ -82,7 +82,7 @@
         }
 
         label:hover {
-            background: $main-accent;
+            background: $medium-gray;
             transform: scale(1.15);
         }
 
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index dc5231a3a..328d7c081 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 
 .collectionMenu-cont {
@@ -407,7 +407,7 @@
             }
 
             .switchToText {
-                color: $main-accent;
+                color: $medium-gray;
             }
 
             .switchToText:hover {
@@ -534,7 +534,7 @@
     .collectionSchemaViewChrome-togglerButton {
         width: 47px;
         height: 30px;
-        background-color: $light-color-secondary;
+        background-color: $light-gray;
         // position: absolute;
         transition: all 0.5s ease;
         // top: 3px;
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 2e6186680..ee6d446f8 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -26,7 +26,7 @@ import { SnappingManager } from "../../util/SnappingManager";
 import { undoBatch } from "../../util/UndoManager";
 import '../DocumentDecorations.scss';
 import { EditableView } from "../EditableView";
-import { MAX_ROW_HEIGHT } from '../globalCssVariables.scss';
+import { MAX_ROW_HEIGHT } from '../global/globalCssVariables.scss';
 import { DocumentIconContainer } from "../nodes/DocumentIcon";
 import { OverlayView } from "../OverlayView";
 import "./CollectionSchemaView.scss";
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 2bdd280ec..d529f097e 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -1,8 +1,8 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .collectionSchemaView-container {
     border-width: $COLLECTION_BORDER_WIDTH;
-    border-color: $intermediate-color;
+    border-color: $medium-gray;
     border-style: solid;
     border-radius: $border-radius;
     box-sizing: border-box;
@@ -39,13 +39,13 @@
     }
 
     // .documentView-node:first-child {
-    //     background: $light-color;
+    //     background: $white;
     // }
 }
 
 .collectionSchemaView-searchContainer {
     border-width: $COLLECTION_BORDER_WIDTH;
-    border-color: $intermediate-color;
+    border-color: $medium-gray;
     border-style: solid;
     border-radius: $border-radius;
     box-sizing: border-box;
@@ -83,7 +83,7 @@
     }
 
     // .documentView-node:first-child {
-    //     background: $light-color;
+    //     background: $white;
     // }
 }
 
@@ -282,7 +282,7 @@ button.add-column {
     }
 
     label {
-        color: $main-accent;
+        color: $medium-gray;
         font-weight: normal;
         letter-spacing: 2px;
         text-transform: uppercase;
@@ -300,12 +300,12 @@ button.add-column {
         transition: background-color 0.2s;
 
         &:hover {
-            background-color: $light-color-secondary;
+            background-color: $light-gray;
         }
 
         &.active {
             font-weight: bold;
-            border: 2px solid $light-color-secondary;
+            border: 2px solid $light-gray;
         }
 
         svg {
@@ -321,7 +321,7 @@ button.add-column {
         background-color: white;
 
         input {
-            border: 2px solid $light-color-secondary;
+            border: 2px solid $light-gray;
             padding: 3px;
             height: 28px;
             font-weight: bold;
@@ -352,7 +352,7 @@ button.add-column {
                 }
 
                 &:hover {
-                    background-color: $light-color-secondary;
+                    background-color: $light-gray;
                 }
             }
         }
@@ -382,7 +382,7 @@ button.add-column {
     background-color: white;
 
     &.row-focused .rt-td {
-        background-color: #bfffc0; //$light-color-secondary;
+        background-color: #bfffc0; //$light-gray;
     }
 
     &.row-wrapped {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index b33c437a9..18926264d 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -16,7 +16,7 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { SnappingManager } from "../../util/SnappingManager";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss';
+import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss';
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import '../DocumentDecorations.scss';
@@ -147,43 +147,43 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
         const anyType = <div className={"columnMenu-option" + (type === ColumnType.Any ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Any)}>
             <FontAwesomeIcon icon={"align-justify"} size="sm" />
-                Any
-            </div>;
+            Any
+        </div>;
 
         const numType = <div className={"columnMenu-option" + (type === ColumnType.Number ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Number)}>
             <FontAwesomeIcon icon={"hashtag"} size="sm" />
-                Number
-            </div>;
+            Number
+        </div>;
 
         const textType = <div className={"columnMenu-option" + (type === ColumnType.String ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.String)}>
             <FontAwesomeIcon icon={"font"} size="sm" />
             Text
-            </div>;
+        </div>;
 
         const boolType = <div className={"columnMenu-option" + (type === ColumnType.Boolean ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Boolean)}>
             <FontAwesomeIcon icon={"check-square"} size="sm" />
             Checkbox
-            </div>;
+        </div>;
 
         const listType = <div className={"columnMenu-option" + (type === ColumnType.List ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.List)}>
             <FontAwesomeIcon icon={"list-ul"} size="sm" />
             List
-            </div>;
+        </div>;
 
         const docType = <div className={"columnMenu-option" + (type === ColumnType.Doc ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Doc)}>
             <FontAwesomeIcon icon={"file"} size="sm" />
             Document
-            </div>;
+        </div>;
 
         const imageType = <div className={"columnMenu-option" + (type === ColumnType.Image ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Image)}>
             <FontAwesomeIcon icon={"image"} size="sm" />
             Image
-            </div>;
+        </div>;
 
         const dateType = <div className={"columnMenu-option" + (type === ColumnType.Date ? " active" : "")} onClick={() => this.setColumnType(col, ColumnType.Date)}>
             <FontAwesomeIcon icon={"calendar"} size="sm" />
-                Date
-                </div>;
+            Date
+        </div>;
 
 
         const allColumnTypes = <div className="columnMenu-types">
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 9f56a0c0e..f103d9581 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .collectionMasonryView {
     display: inline;
@@ -97,7 +97,7 @@
         width: 100%;
         font-family: $sans-serif;
         background: $dark-color;
-        color: $light-color;
+        color: $white;
     }
 
     .collectionStackingView-columnDragger {
@@ -128,7 +128,7 @@
         margin-left: 2px;
         margin-right: 2px;
         margin-top: 2px;
-        background: $main-accent;
+        background: $medium-gray;
         height: 5px;
 
         &.active {
@@ -180,11 +180,11 @@
     .collectionStackingView-sectionHeader {
         text-align: center;
         margin: auto;
-        background: $main-accent;
+        background: $medium-gray;
         // overflow: hidden; overflow is visible so the color menu isn't hidden -ftong
 
         .editableView-input {
-            color: black;
+            color: $dark-color;
         }
 
         .editableView-input:hover,
@@ -205,7 +205,7 @@
             display: flex;
             align-items: center;
             justify-content: center;
-            color: black;
+            color: $dark-color;
 
             .editableView-container-editing-oneLine,
             .editableView-container-editing {
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 72ab51784..ec461ab94 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .collectionTreeView-dropTarget {
     border-width: $COLLECTION_BORDER_WIDTH;
@@ -12,7 +12,7 @@
     top: 0;
     padding-left: 10px;
     padding-right: 10px;
-    background: $light-color-secondary;
+    background: $light-gray;
     font-size: 13px;
     overflow: auto;
     user-select: none;
@@ -40,7 +40,7 @@
     }
 
     .delete-button {
-        color: $intermediate-color;
+        color: $medium-gray;
         // float: right;
         margin-left: 15px;
         // margin-top: 3px;
@@ -71,7 +71,7 @@
 .collectionTreeView-subtitle {
     font-style: italic;
     font-size: 8pt;
-    color: $intermediate-color;
+    color: $medium-gray;
 }
 
 .docContainer {
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index a5aef86de..5db489c0a 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -1,8 +1,8 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .collectionView {
     border-width: 0;
-    border-color: $light-color-secondary;
+    border-color: $light-gray;
     border-style: solid;
     border-radius: 0 0 $border-radius $border-radius;
     box-sizing: border-box;
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 0c69ee030..84560cf26 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -21,7 +21,7 @@ import { DocumentType } from "../../documents/DocumentTypes";
 import { CompileScript, Transformer, ts } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/globalCssVariables.scss';
+import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss';
 import { ContextMenu } from "../ContextMenu";
 import '../DocumentDecorations.scss';
 import { DocumentView } from "../nodes/DocumentView";
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 3f6fc8b0c..1ebc5873e 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .treeView-label {
     max-height: 1.5em;
@@ -14,7 +14,7 @@
     .bullet-outline {
         position: relative;
         width: $TREE_BULLET_WIDTH;
-        color: $intermediate-color;
+        color: $medium-gray;
         transform: scale(0.5);
         display: inline-flex;
         align-items: center;
@@ -45,7 +45,7 @@
     .bullet {
         position: relative;
         width: $TREE_BULLET_WIDTH;
-        color: $intermediate-color;
+        color: $medium-gray;
         margin-top: 3px;
         transform: scale(1.3, 1.3);
         border: #80808030 1px solid;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 2e98fb508..4f9a966f2 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -20,7 +20,7 @@ import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from '../../util/UndoManager';
 import { EditableView } from "../EditableView";
-import { TREE_BULLET_WIDTH } from '../globalCssVariables.scss';
+import { TREE_BULLET_WIDTH } from '../global/globalCssVariables.scss';
 import { DocumentView, DocumentViewProps, StyleProviderFunc, DocumentViewInternal } from '../nodes/DocumentView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
index c5b8fc5e8..5fa01b102 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.scss
@@ -1,4 +1,4 @@
-@import "globalCssVariables";
+@import "global/globalCssVariables";
 
 .collectionFreeFormRemoteCursors-cont {
     
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
index eb0538c41..79e063f7f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
 
 .collectionfreeformview-none {
     position: inherit;
@@ -226,7 +226,7 @@
     //   linear-gradient(to bottom, $light-color-secondary 1px, transparent 1px);
     // background-size: 30px 30px;
     // }
-    border: 0px solid $light-color-secondary;
+    border: 0px solid $light-gray;
     border-radius: inherit;
     box-sizing: border-box;
     position: absolute;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index accb80c5a..a4e310e6c 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -28,7 +28,7 @@ import { SelectionManager } from "../../../util/SelectionManager";
 import { SnappingManager } from "../../../util/SnappingManager";
 import { Transform } from "../../../util/Transform";
 import { undoBatch } from "../../../util/UndoManager";
-import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
+import { COLLECTION_BORDER_WIDTH } from "../../../views/global/globalCssVariables.scss";
 import { Timeline } from "../../animationtimeline/Timeline";
 import { ContextMenu } from "../../ContextMenu";
 import { DocumentDecorations } from "../../DocumentDecorations";
@@ -834,10 +834,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 map(doc => ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") }));
             if (measuredDocs.length) {
                 const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) =>  // computes range of content
-                    ({
-                        xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
-                        yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
-                    })
+                ({
+                    xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
+                    yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
+                })
                     , {
                         xrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE },
                         yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
new file mode 100644
index 000000000..218bdbf3c
--- /dev/null
+++ b/src/client/views/global/globalCssVariables.scss
@@ -0,0 +1,52 @@
+@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Crimson+Text:400,400i,700");
+// colors
+$white: #ffffff;
+$light-gray:#dfdfdf;
+$medium-gray: #9F9F9F;
+
+$lighter-alt-accent: rgb(207, 220, 240);
+$darker-alt-accent: #b2cef8;
+
+$dark-color: #111111;
+$link-color: #add8e6;
+$antimodemenu-height: 35px;
+// fonts
+$sans-serif: "Noto Sans",
+sans-serif;
+// $sans-serif: "Roboto Slab", sans-serif;
+$serif: "Crimson Text",
+serif;
+// misc values
+$border-radius: 0.3em;
+//
+$search-thumnail-size: 130;
+
+// dragged items
+$contextMenu-zindex: 100000; // context menu shows up over everything
+$radialMenu-zindex: 100000; // context menu shows up over everything
+
+$searchpanel-height: 32px;
+$mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc
+$docDecorations-zindex: 998; // then doc decorations appear over everything else
+$remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right?
+$COLLECTION_BORDER_WIDTH: 0;
+$SCHEMA_DIVIDER_WIDTH: 4;
+$MINIMIZED_ICON_SIZE:25;
+$MAX_ROW_HEIGHT: 44px;
+$DFLT_IMAGE_NATIVE_DIM: 900px;
+$MENU_PANEL_WIDTH: 60px;
+$TREE_BULLET_WIDTH: 20px;
+
+:export {
+    contextMenuZindex: $contextMenu-zindex;
+    SCHEMA_DIVIDER_WIDTH: $SCHEMA_DIVIDER_WIDTH;
+    COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH;
+    MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE;
+    MAX_ROW_HEIGHT: $MAX_ROW_HEIGHT;
+    SEARCH_THUMBNAIL_SIZE: $search-thumnail-size;
+    ANTIMODEMENU_HEIGHT: $antimodemenu-height;
+    SEARCH_PANEL_HEIGHT: $searchpanel-height;
+    DFLT_IMAGE_NATIVE_DIM: $DFLT_IMAGE_NATIVE_DIM;
+    MENU_PANEL_WIDTH: $MENU_PANEL_WIDTH;
+    TREE_BULLET_WIDTH: $TREE_BULLET_WIDTH;
+}
\ No newline at end of file
diff --git a/src/client/views/global/globalCssVariables.scss.d.ts b/src/client/views/global/globalCssVariables.scss.d.ts
new file mode 100644
index 000000000..11e62e1eb
--- /dev/null
+++ b/src/client/views/global/globalCssVariables.scss.d.ts
@@ -0,0 +1,17 @@
+
+interface IGlobalScss {
+    contextMenuZindex: string;  // context menu shows up over everything
+    SCHEMA_DIVIDER_WIDTH: string;
+    COLLECTION_BORDER_WIDTH: string;
+    MINIMIZED_ICON_SIZE: string;
+    MAX_ROW_HEIGHT: string;
+    SEARCH_THUMBNAIL_SIZE: string;
+    ANTIMODEMENU_HEIGHT: string;
+    SEARCH_PANEL_HEIGHT: string;
+    DFLT_IMAGE_NATIVE_DIM: string;
+    MENU_PANEL_WIDTH: string;
+    TREE_BULLET_WIDTH: string;
+}
+declare const globalCssVariables: IGlobalScss;
+
+export = globalCssVariables;
\ No newline at end of file
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
new file mode 100644
index 000000000..9d182ee0f
--- /dev/null
+++ b/src/client/views/global/globalEnums.tsx
@@ -0,0 +1,19 @@
+export enum Colors {
+    DarkGray = "#111111",
+    MediumGray = "#9F9F9F",
+    LightGray = "#DFDFDF",
+    White = "#FFFFFF",
+    MediumBlue = "#4476F7",
+    LightBlue = "#BDDDF5",
+    Pink = "#E0217D",
+    Yellow = "#F5D747"
+}
+
+export enum FontSizes {
+    LargeHeader = "16px"
+
+}
+
+export enum Padding {
+
+}
\ No newline at end of file
diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss
deleted file mode 100644
index ccc9306c4..000000000
--- a/src/client/views/globalCssVariables.scss
+++ /dev/null
@@ -1,56 +0,0 @@
-@import url("https://fonts.googleapis.com/css?family=Noto+Sans:400,700|Crimson+Text:400,400i,700");
-// colors
-$light-color: #fcfbf7;
-$light-color-secondary:#f1efeb;
-//$main-accent: #61aaa3;
-$main-accent: #aaaaa3;
-// $alt-accent: #cdd5ec;
-// $alt-accent: #cdeceb;
-//$alt-accent: #59dff7;
-$alt-accent: #c2c2c5;
-$lighter-alt-accent: rgb(207, 220, 240);
-$darker-alt-accent: #b2cef8;
-$intermediate-color: #9c9396;
-$dark-color: #121721;
-$link-color: #add8e6;
-$antimodemenu-height: 35px;
-// fonts
-$sans-serif: "Noto Sans",
-sans-serif;
-// $sans-serif: "Roboto Slab", sans-serif;
-$serif: "Crimson Text",
-serif;
-// misc values
-$border-radius: 0.3em;
-//
-$search-thumnail-size: 130;
-
-// dragged items
-$contextMenu-zindex: 100000; // context menu shows up over everything
-$radialMenu-zindex: 100000; // context menu shows up over everything
-
-$searchpanel-height: 32px;
-$mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc
-$docDecorations-zindex: 998; // then doc decorations appear over everything else
-$remoteCursors-zindex: 997; // ... not sure what level the remote cursors should go -- is this right?
-$COLLECTION_BORDER_WIDTH: 0;
-$SCHEMA_DIVIDER_WIDTH: 4;
-$MINIMIZED_ICON_SIZE:25;
-$MAX_ROW_HEIGHT: 44px;
-$DFLT_IMAGE_NATIVE_DIM: 900px;
-$MENU_PANEL_WIDTH: 60px;
-$TREE_BULLET_WIDTH: 20px;
-
-:export {
-    contextMenuZindex: $contextMenu-zindex;
-    SCHEMA_DIVIDER_WIDTH: $SCHEMA_DIVIDER_WIDTH;
-    COLLECTION_BORDER_WIDTH: $COLLECTION_BORDER_WIDTH;
-    MINIMIZED_ICON_SIZE: $MINIMIZED_ICON_SIZE;
-    MAX_ROW_HEIGHT: $MAX_ROW_HEIGHT;
-    SEARCH_THUMBNAIL_SIZE: $search-thumnail-size;
-    ANTIMODEMENU_HEIGHT: $antimodemenu-height;
-    SEARCH_PANEL_HEIGHT: $searchpanel-height;
-    DFLT_IMAGE_NATIVE_DIM: $DFLT_IMAGE_NATIVE_DIM;
-    MENU_PANEL_WIDTH: $MENU_PANEL_WIDTH;
-    TREE_BULLET_WIDTH: $TREE_BULLET_WIDTH;
-}
\ No newline at end of file
diff --git a/src/client/views/globalCssVariables.scss.d.ts b/src/client/views/globalCssVariables.scss.d.ts
deleted file mode 100644
index 11e62e1eb..000000000
--- a/src/client/views/globalCssVariables.scss.d.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-
-interface IGlobalScss {
-    contextMenuZindex: string;  // context menu shows up over everything
-    SCHEMA_DIVIDER_WIDTH: string;
-    COLLECTION_BORDER_WIDTH: string;
-    MINIMIZED_ICON_SIZE: string;
-    MAX_ROW_HEIGHT: string;
-    SEARCH_THUMBNAIL_SIZE: string;
-    ANTIMODEMENU_HEIGHT: string;
-    SEARCH_PANEL_HEIGHT: string;
-    DFLT_IMAGE_NATIVE_DIM: string;
-    MENU_PANEL_WIDTH: string;
-    TREE_BULLET_WIDTH: string;
-}
-declare const globalCssVariables: IGlobalScss;
-
-export = globalCssVariables;
\ No newline at end of file
diff --git a/src/client/views/linking/LinkEditor.scss b/src/client/views/linking/LinkEditor.scss
index 7e6999cdc..eee072ed5 100644
--- a/src/client/views/linking/LinkEditor.scss
+++ b/src/client/views/linking/LinkEditor.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .linkEditor {
     width: 100%;
@@ -20,7 +20,7 @@
 }
 
 .linkEditor-info {
-    //border-bottom: 0.5px solid $light-color-secondary;
+    //border-bottom: 0.5px solid $light-gray;
     //padding-bottom: 1px;
     padding-top: 5px;
     padding-left: 5px;
@@ -195,7 +195,7 @@
 }
 
 .linkEditor-group {
-    background-color: $light-color-secondary;
+    background-color: $light-gray;
     padding: 6px;
     margin: 3px 0;
     border-radius: 3px;
@@ -254,8 +254,8 @@
     }
 
     .linkEditor-option {
-        background-color: $light-color-secondary;
-        border: 1px solid $intermediate-color;
+        background-color: $light-gray;
+        border: 1px solid $medium-gray;
         border-top: 0;
         padding: 3px;
         cursor: pointer;
@@ -285,7 +285,7 @@
     width: calc(100% - 40px);
 
     &:hover {
-        background-color: $light-color;
+        background-color: $white;
     }
 }
 
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index a90bf8b0a..a2ea42999 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .linkMenu {
     width: auto;
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
index 4e13ef8c8..a07e540ae 100644
--- a/src/client/views/linking/LinkMenuItem.scss
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -1,7 +1,7 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .linkMenu-item {
-    // border-top: 0.5px solid $main-accent; 
+    // border-top: 0.5px solid $medium-gray; 
     position: relative;
     display: flex;
     border-bottom: 0.5px solid black;
@@ -102,7 +102,7 @@
     .link-metadata {
         padding: 0 10px 0 16px;
         margin-bottom: 4px;
-        color: $main-accent;
+        color: $medium-gray;
         font-style: italic;
         font-size: 10.5px;
     }
@@ -144,7 +144,7 @@
         border-radius: 50%;
         pointer-events: auto;
         background-color: $dark-color;
-        color: $light-color;
+        color: $white;
         font-size: 65%;
         transition: transform 0.2s;
         text-align: center;
@@ -162,7 +162,7 @@
         }
 
         &:hover {
-            background: $main-accent;
+            background: $medium-gray;
             cursor: pointer;
         }
     }
diff --git a/src/client/views/nodes/DocumentLinksButton.scss b/src/client/views/nodes/DocumentLinksButton.scss
index 735aa669f..daffaf9e7 100644
--- a/src/client/views/nodes/DocumentLinksButton.scss
+++ b/src/client/views/nodes/DocumentLinksButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables.scss";
+@import "../global/globalCssVariables.scss";
 
 
 .documentLinksButton-cont {
@@ -37,7 +37,7 @@
     font-weight: bold;
 
     &:hover {
-        background: $main-accent;
+        background: $medium-gray;
         transform: scale(1.05);
         cursor: pointer;
     }
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index bdbece621..8f86417d6 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .documentView-effectsWrapper {
     border-radius: inherit;
@@ -22,7 +22,7 @@
     transition: outline .3s linear;
     cursor: grab;
 
-    // background: $light-color; //overflow: hidden;
+    // background: $white; //overflow: hidden;
     transform-origin: left top;
 
     &.minimized {
@@ -218,6 +218,6 @@
 
     .documentView-node:first-child {
         position: relative;
-        background: "#B59B66"; //$light-color;
+        background: "#B59B66"; //$white;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/KeyValueBox.scss b/src/client/views/nodes/KeyValueBox.scss
index eb7c2f32b..ffcba4981 100644
--- a/src/client/views/nodes/KeyValueBox.scss
+++ b/src/client/views/nodes/KeyValueBox.scss
@@ -1,10 +1,10 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 .keyValueBox-cont {
     overflow-y: scroll;
     width:100%;
     height: 100%;
-    background-color: $light-color;
-    border: 1px solid $intermediate-color;
+    background-color: $white;
+    border: 1px solid $medium-gray;
     border-radius: $border-radius;
     box-sizing: border-box;
     display: inline-block;
@@ -56,8 +56,8 @@ $header-height: 30px;
     width:100%;
     position: relative;
     display: inline-block;
-    background: $intermediate-color;
-    color: $light-color;
+    background: $medium-gray;
+    color: $white;
     text-transform: uppercase;
     letter-spacing: 2px;
     font-size: 12px;
@@ -66,7 +66,7 @@ $header-height: 30px;
     th {
         font-weight: normal;
         &:first-child {
-            border-right: 1px solid $light-color;
+            border-right: 1px solid $white;
         }
     }
 }
@@ -76,9 +76,9 @@ $header-height: 30px;
     display: flex;
     width:100%;
     height:$header-height;
-    background: $light-color;
+    background: $white;
     .formattedTextBox-cont {
-        background: $light-color;
+        background: $white;
     }
 }
 .keyValueBox-cont {
@@ -116,8 +116,8 @@ $header-height: 30px;
     display: flex;
     width:100%;
     height:30px;
-    background: $light-color-secondary;
+    background: $light-gray;
     .formattedTextBox-cont {
-        background: $light-color-secondary;
+        background: $light-gray;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss
index f78767234..5b660e582 100644
--- a/src/client/views/nodes/KeyValuePair.scss
+++ b/src/client/views/nodes/KeyValuePair.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 
 .keyValuePair-td-key {
diff --git a/src/client/views/nodes/RadialMenu.scss b/src/client/views/nodes/RadialMenu.scss
index daa620d12..312b51013 100644
--- a/src/client/views/nodes/RadialMenu.scss
+++ b/src/client/views/nodes/RadialMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .radialMenu-cont {
     position: absolute;
@@ -53,7 +53,7 @@ s
     transition: all .1s;
     border-width: .11px;
     border-style: none;
-    border-color: $intermediate-color; //  rgb(187, 186, 186);
+    border-color: $medium-gray; //  rgb(187, 186, 186);
     // padding: 10px 0px 10px 0px;
     white-space: nowrap;
     font-size: 13px;
diff --git a/src/client/views/nodes/WebBox.scss b/src/client/views/nodes/WebBox.scss
index ca82c049c..e206508d3 100644
--- a/src/client/views/nodes/WebBox.scss
+++ b/src/client/views/nodes/WebBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables.scss";
+@import "../global/globalCssVariables.scss";
 
 
 .webBox {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 53aceb533..3cedab1a4 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
 
 .ProseMirror {
     width: 100%;
@@ -31,7 +31,7 @@ audiotag:hover {
     padding: 0;
     border-width: 0px;
     border-radius: inherit;
-    border-color: $intermediate-color;
+    border-color: $medium-gray;
     box-sizing: border-box;
     background-color: inherit;
     border-style: solid;
@@ -363,7 +363,7 @@ footnote::after {
 
 
 @media only screen and (max-width: 1000px) {
-    @import "../../globalCssVariables";
+    @import "../../global/globalCssVariables";
 
     .ProseMirror {
         width: 100%;
@@ -381,7 +381,7 @@ footnote::after {
         padding: 0;
         border-width: 0px;
         border-radius: inherit;
-        border-color: $intermediate-color;
+        border-color: $medium-gray;
         box-sizing: border-box;
         background-color: inherit;
         border-style: solid;
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.scss b/src/client/views/nodes/formattedText/RichTextMenu.scss
index 1d24d6833..c94e93541 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.scss
+++ b/src/client/views/nodes/formattedText/RichTextMenu.scss
@@ -1,4 +1,4 @@
-@import "../../globalCssVariables";
+@import "../../global/globalCssVariables";
 
 .button-dropdown-wrapper {
     position: relative;
@@ -24,7 +24,7 @@
         top: 35px;
         left: 0;
         background-color: #323232;
-        color: $light-color-secondary;
+        color: $light-gray;
         border: 1px solid #4d4d4d;
         border-radius: 0 6px 6px 6px;
         box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
diff --git a/src/client/views/nodes/formattedText/TooltipTextMenu.scss b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
index 0e4b752ac..8c4d77da9 100644
--- a/src/client/views/nodes/formattedText/TooltipTextMenu.scss
+++ b/src/client/views/nodes/formattedText/TooltipTextMenu.scss
@@ -1,4 +1,4 @@
-@import "../views/globalCssVariables";
+@import "../views/global/globalCssVariables";
 .ProseMirror-menu-dropdown-wrap {
     display: inline-block;
     position: relative;
@@ -50,7 +50,7 @@
         padding: 3px;
 
         &:hover {
-            background-color: $light-color-secondary;
+            background-color: $light-gray;
         }
     }
 }
@@ -294,9 +294,9 @@
         top: 31px;
         background-color: #323232;
         border: 1px solid #4d4d4d;
-        color: $light-color-secondary;
+        color: $light-gray;
         // border: none;
-        // border: 1px solid $light-color-secondary;
+        // border: 1px solid $light-gray;
         border-radius: 0 6px 6px 6px;
         padding: 3px;
         box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
@@ -323,7 +323,7 @@
             }
 
             .separated-button {
-                border-top: 1px solid $light-color-secondary;
+                border-top: 1px solid $light-gray;
                 padding-top: 6px;
             }
 
diff --git a/src/client/views/search/CheckBox.scss b/src/client/views/search/CheckBox.scss
index cc858bec6..c46b3eb20 100644
--- a/src/client/views/search/CheckBox.scss
+++ b/src/client/views/search/CheckBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .checkboxfilter {
     display: flex;
@@ -40,7 +40,7 @@
             overflow: visible;
             background-color: transparent;
             border-style: solid;
-            border-color: $alt-accent;
+            border-color: $medium-gray;
             border-width: 2px;
             -webkit-transition: all 0.2s ease-in-out;
             -moz-transition: all 0.2s ease-in-out;
diff --git a/src/client/views/search/CollectionFilters.scss b/src/client/views/search/CollectionFilters.scss
index b54cdcbd1..845b16f67 100644
--- a/src/client/views/search/CollectionFilters.scss
+++ b/src/client/views/search/CollectionFilters.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .collection-filters {
     display: flex;
diff --git a/src/client/views/search/IconBar.scss b/src/client/views/search/IconBar.scss
index 013dcd57e..6aaf7918d 100644
--- a/src/client/views/search/IconBar.scss
+++ b/src/client/views/search/IconBar.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .icon-bar {
     display: flex;
diff --git a/src/client/views/search/IconButton.scss b/src/client/views/search/IconButton.scss
index 4ec03c7c9..d87b8bd5c 100644
--- a/src/client/views/search/IconButton.scss
+++ b/src/client/views/search/IconButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .type-outer {
     display: flex;
@@ -9,7 +9,7 @@
     .type-icon {
         height: 30px;
         width: 30px;
-        color: $light-color;
+        color: $white;
         // background-color: rgb(194, 194, 197);
         background-color: gray;
         border-radius: 50%;
diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx
index 349690b20..6fd91c9c1 100644
--- a/src/client/views/search/IconButton.tsx
+++ b/src/client/views/search/IconButton.tsx
@@ -4,7 +4,7 @@ import { action, IReactionDisposer, observable, reaction, runInAction } from 'mo
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { DocumentType } from "../../documents/DocumentTypes";
-import '../globalCssVariables.scss';
+import '../global/globalCssVariables.scss';
 import { IconBar } from './IconBar';
 import "./IconButton.scss";
 import "./SearchBox.scss";
diff --git a/src/client/views/search/NaviconButton.scss b/src/client/views/search/NaviconButton.scss
index c23bab461..8a70b29de 100644
--- a/src/client/views/search/NaviconButton.scss
+++ b/src/client/views/search/NaviconButton.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 $height-icon: 15px;
 $width-line: 30px;
@@ -20,7 +20,7 @@ $translateX: 0;
 
     .line {
         display: block;
-        background: $alt-accent;
+        background: $medium-gray;
         width: $width-line;
         height: $height-line;
         position: absolute;
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 4f5b7e41a..8d6bc86cb 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 @import "./NaviconButton.scss";
 
 .searchBox-container {
@@ -20,7 +20,7 @@
         display: flex;
         justify-content: center;
         align-items: center;
-        background-color: black;
+        background-color: $dark-color;
 
         .searchBox-lozenges {
             position: absolute;
@@ -86,7 +86,7 @@
             &.searchBox-input {
                 margin:5px;
                 border-radius:20px;
-                border:black;    
+                border:$dark-color;    
                 display: block;
                 width: 130px;
                 -webkit-transition: width 0.4s;
@@ -114,7 +114,7 @@
             }
 
             &.searchBox-close {
-                color: $light-color;
+                color: $white;
                 max-height: $searchpanel-height;
             }
         }
@@ -132,7 +132,7 @@
 
     .no-result {
         width: 500px;
-        background: $light-color-secondary;
+        background: $light-gray;
         padding: 10px;
         height: 50px;
         text-transform: uppercase;
diff --git a/src/client/views/search/SelectorContextMenu.scss b/src/client/views/search/SelectorContextMenu.scss
index 48cacc608..438b6a0c2 100644
--- a/src/client/views/search/SelectorContextMenu.scss
+++ b/src/client/views/search/SelectorContextMenu.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .parents {
     background: $lighter-alt-accent;
diff --git a/src/client/views/search/ToggleBar.scss b/src/client/views/search/ToggleBar.scss
index 79f866acb..3a164f133 100644
--- a/src/client/views/search/ToggleBar.scss
+++ b/src/client/views/search/ToggleBar.scss
@@ -1,9 +1,9 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .toggle-title {
     display: flex;
     align-items: center;
-    color: $light-color;
+    color: $white;
     text-transform: uppercase;
     flex-direction: row;
     justify-content: space-around;
@@ -25,7 +25,7 @@
     // height: 50px;
     height: 30px;
     width: 100px;
-    background-color: $alt-accent;
+    background-color: $medium-gray;
     border-radius: 10px;
     padding: 5px;
     display: flex;
@@ -36,6 +36,6 @@
         width: 40px;
         height: 100%;
         border-radius: 10px;
-        background-color: $light-color;
+        background-color: $white;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/webcam/DashWebRTCVideo.scss b/src/client/views/webcam/DashWebRTCVideo.scss
index 41307a808..249aee9d6 100644
--- a/src/client/views/webcam/DashWebRTCVideo.scss
+++ b/src/client/views/webcam/DashWebRTCVideo.scss
@@ -1,4 +1,4 @@
-@import "../globalCssVariables";
+@import "../global/globalCssVariables";
 
 .webcam-cont {
     background: whitesmoke;
diff --git a/src/mobile/AudioUpload.scss b/src/mobile/AudioUpload.scss
index 6e64d9e2e..dce0c724f 100644
--- a/src/mobile/AudioUpload.scss
+++ b/src/mobile/AudioUpload.scss
@@ -1,4 +1,4 @@
-@import "../client/views/globalCssVariables.scss";
+@import "../client/views/global/globalCssVariables.scss";
 
 .audioUpload_cont {
     display: flex;
diff --git a/src/mobile/ImageUpload.scss b/src/mobile/ImageUpload.scss
index 890258918..6669a3d21 100644
--- a/src/mobile/ImageUpload.scss
+++ b/src/mobile/ImageUpload.scss
@@ -1,4 +1,4 @@
-@import "../client/views/globalCssVariables.scss";
+@import "../client/views/global/globalCssVariables.scss";
 
 .imgupload_cont {
     display: flex;
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 2183d2172..98696496f 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -5,7 +5,7 @@ import * as rp from 'request-promise';
 import { DocServer } from '../client/DocServer';
 import { Docs } from '../client/documents/Documents';
 import { Networking } from '../client/Network';
-import { DFLT_IMAGE_NATIVE_DIM } from '../client/views/globalCssVariables.scss';
+import { DFLT_IMAGE_NATIVE_DIM } from '../client/views/global/globalCssVariables.scss';
 import { MainViewModal } from '../client/views/MainViewModal';
 import { Doc, Opt } from '../fields/Doc';
 import { List } from '../fields/List';
-- 
cgit v1.2.3-70-g09d2


From 48dbde117728e4b36bae11f0f16a796059ecf7ee Mon Sep 17 00:00:00 2001
From: dg314 <david_grossman@brown.edu>
Date: Sat, 17 Jul 2021 15:13:39 -0400
Subject: initial search panel

---
 src/client/util/CurrentUserUtils.ts                |  27 ++++-
 src/client/views/MainView.tsx                      |  11 +-
 src/client/views/StyleProvider.tsx                 |   2 +-
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 src/client/views/collections/SchemaTable.tsx       |   3 +-
 src/client/views/search/SearchBox.tsx              | 117 ++-------------------
 6 files changed, 41 insertions(+), 121 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 12733e815..596ccd9a6 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -35,6 +35,8 @@ import { UndoManager } from "./UndoManager";
 import { SnappingManager } from "./SnappingManager";
 import { InkTool } from "../../fields/InkField";
 import { computedFn } from "mobx-utils";
+import { CollectionSchemaBooleanCell } from "../views/collections/CollectionSchemaCells";
+import { Console } from "console";
 
 
 export let resolvedPorts: { server: number, socket: number };
@@ -53,6 +55,7 @@ export class CurrentUserUtils {
     @observable public static GuestDashboard: Doc | undefined;
     @observable public static GuestMobile: Doc | undefined;
     @observable public static propertiesWidth: number = 0;
+    @observable public static searchPanelWidth: number = 0;
 
     // sets up the default User Templates - slideView,  headerView
     static setupUserTemplateButtons(doc: Doc) {
@@ -516,6 +519,7 @@ export class CurrentUserUtils {
     static async menuBtnDescriptions(doc: Doc) {
         return [
             { title: "Dashboards", target: Cast(doc.myDashboards, Doc, null), icon: "desktop", click: 'selectMainMenu(self)' },
+            { title: "Search", target: Cast(doc.mySearchPanel, Doc, null), icon: "search", click: 'selectMainMenu(self)' },
             { title: "My Files", target: Cast(doc.myFilesystem, Doc, null), icon: "file", click: 'selectMainMenu(self)' },
             { title: "Tools", target: Cast(doc.myTools, Doc, null), icon: "wrench", click: 'selectMainMenu(self)' },
             { title: "Import", target: Cast(doc.myImportPanel, Doc, null), icon: "upload", click: 'selectMainMenu(self)' },
@@ -529,14 +533,15 @@ export class CurrentUserUtils {
         ];
     }
 
-    static setupSearchPanel(doc: Doc) {
+    /*static setupSearchPanel(doc: Doc) {
         if (doc.mySearchPanelDoc === undefined) {
             doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({
                 _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
                 childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
             })) as any as Doc;
         }
-    }
+    }*/
+
     static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
         if (doc.menuStack === undefined) {
             await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId);  // sets up the right sidebar collection for mobile upload documents and sharing
@@ -807,6 +812,7 @@ export class CurrentUserUtils {
             (doc.myRecentlyClosedDocs as any as Doc).contextMenuLabels = new List<string>(["Clear All"]);
         }
     }
+
     static setupFilterDocs(doc: Doc) {
         // setup Filter item
         if (doc.currentFilter === undefined) {
@@ -939,6 +945,21 @@ export class CurrentUserUtils {
         }
     }
 
+    // Search sidebar is where searches within the document are performed
+    static setupSearchSidebar(doc: Doc) {
+        if (doc.mySearchPanelDoc === undefined) {
+            doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({
+                _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
+                childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
+            })) as any as Doc;
+        }
+        if (doc.mySearchPanel === undefined) {
+            const searchPanelDoc = Cast(doc.mySearchPanelDoc, Doc, null);
+            //const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
+            doc.mySearchPanel = new PrefetchProxy(Docs.Create.StackingDocument([searchPanelDoc], { title: "Search", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true }));
+        }
+    }
+
     static setupClickEditorTemplates(doc: Doc) {
         if (doc["clickFuncs-child"] === undefined) {
             // to use this function, select it from the context menu of a collection.  then edit the onChildClick script.  Add two Doc variables: 'target' and 'thisContainer', then assign 'target' to some target collection.  After that, clicking on any document in the initial collection will open it in the target
@@ -1023,8 +1044,8 @@ export class CurrentUserUtils {
         this.setupDefaultIconTemplates(doc);  // creates a set of icon templates triggered by the document deoration icon
         this.setupDocTemplates(doc); // sets up the template menu of templates
         this.setupImportSidebar(doc);
+        this.setupSearchSidebar(doc); // sets up the search sidebar
         this.setupActiveMobileMenu(doc); // sets up the current mobile menu for Dash Mobile
-        this.setupSearchPanel(doc);
         this.setupOverlays(doc);  // documents in overlay layer
         this.setupDockedButtons(doc);  // the bottom bar of font icons
         await this.setupSidebarButtons(doc); // the pop-out left sidebar of tools/panels
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 4eeb1fc95..bc9c6f4d2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -180,8 +180,8 @@ export class MainView extends React.Component {
             const targClass = targets[0].className.toString();
             if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
-                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                        thing.className === "collectionSchema-header-menuOptions"));
+                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+                    thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
             }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
@@ -388,7 +388,6 @@ export class MainView extends React.Component {
                     SettingsManager.Instance.open();
                     break;
                 case "Catalog":
-                    SearchBox.Instance._searchFullDB = "My Stuff";
                     SearchBox.Instance.enter(undefined);
                     break;
                 case "Help":
@@ -523,7 +522,7 @@ export class MainView extends React.Component {
         </svg>;
     }
 
-    @computed get search() {
+    /*@computed get search() {
         TraceMobx();
         return <div className="mainView-searchPanel">
             <SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
@@ -555,7 +554,7 @@ export class MainView extends React.Component {
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={undefined} />
         </div>;
-    }
+    }*/
 
     @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
         return !DocumentLinksButton.invisibleWebDoc ? null :
@@ -604,7 +603,7 @@ export class MainView extends React.Component {
             <GroupManager />
             <GoogleAuthenticationManager />
             <DocumentDecorations boundsLeft={this.leftOffset} boundsTop={this.topOffset} />
-            {this.search}
+            {/*this.search*/}
             <CollectionMenu />
             {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
             {DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 9e61351c4..e670420d1 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -100,7 +100,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             const backColor = backgroundCol();// || (darkScheme() ? "black" : "white");
             if (!backColor) return undefined;
             const nonAlphaColor = backColor.startsWith("#") ? (backColor as string).substring(0, 7) :
-                backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor
+                backColor.startsWith("rgba") ? backColor.replace(/,.[^,]*\)/, ")").replace("rgba", "rgb") : backColor;
             const col = Color(nonAlphaColor).rgb();
             const colsum = (col.red() + col.green() + col.blue());
             if (colsum / col.alpha() > 400 || col.alpha() < 0.25) return "black";
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index b33c437a9..971dd5cbf 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -556,7 +556,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             style={{
                 overflow: this.props.scrollOverflow === true ? "scroll" : undefined, backgroundColor: "white",
                 pointerEvents: this.props.Document._searchDoc !== undefined && !this.props.isContentActive() && !SnappingManager.GetIsDragging() ? "none" : undefined,
-                width: name === "collectionSchemaView-searchContainer" ? "auto" : this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
+                width: this.props.PanelWidth() || "100%", height: this.props.PanelHeight() || "100%", position: "relative",
             }}  >
             <div className="collectionSchemaView-tableContainer"
                 style={{ width: `calc(100% - ${this.previewWidth()}px)` }}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 0c69ee030..0175b0dc2 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -196,6 +196,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
                     <FontAwesomeIcon icon={sortIcon} size="lg" />
                 </div>
+                {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
             </div>;
 
             return {
@@ -559,7 +560,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()}
             onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
             {this.reactTable}
-            {this.props.Document._chromeHidden ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+            {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
             {!this._showDoc ? (null) :
                 <div className="collectionSchemaView-documentPreview" ref="overlay"
                     style={{
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index b722868d6..740a28825 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -3,9 +3,9 @@ import { Tooltip } from '@material-ui/core';
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, DocListCast, Field, Opt, DocListCastAsync } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym } from '../../../fields/Doc';
 import { documentSchema } from "../../../fields/documentSchemas";
-import { Copy, Id } from '../../../fields/FieldSymbols';
+import { Copy, Id, ToString } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
@@ -52,8 +52,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     private docsforfilter: Doc[] | undefined = [];
     private realTotalResults: number = 0;
     private newsearchstring = "";
-    private collectionRef = React.createRef<HTMLDivElement>();
-
 
     @observable _undoBackground: string | undefined = "";
     @observable _icons: string[] = this._allIcons;
@@ -116,62 +114,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         }
     });
 
-    getFinalQuery(query: string): string {
-        //alters the query so it looks in the correct fields
-        //if this is true, th`en not all of the field boxes are checked
-        //TODO: data
-        const initialfilters = Cast(this.props.Document._docFilters, listSpec("string"), []);
-
-        const filters: string[] = [];
-
-        for (const initFilter of initialfilters) {
-            const fields = initFilter.split(":");
-            if (fields[2] !== undefined) {
-                filters.push(fields[0]);
-                filters.push(fields[1]);
-                filters.push(fields[2]);
-            }
-        }
-
-        const finalfilters: { [key: string]: string[] } = {};
-
-        for (let i = 0; i < filters.length; i = i++) {
-            const fields = filters[i].split(":");
-            if (finalfilters[fields[0]] !== undefined) {
-                finalfilters[fields[0]].push(fields[1]);
-            }
-            else {
-                finalfilters[fields[0]] = [fields[1]];
-            }
-        }
-
-        for (const key in finalfilters) {
-            const values = finalfilters[key];
-            if (values.length === 1) {
-                const mod = "_t:";
-                const newWords: string[] = [];
-                const oldWords = values[0].split(" ");
-                oldWords.forEach((word, i) => i === 0 ? newWords.push(key + mod + word) : newWords.push("AND " + key + mod + word));
-                query = `(${query}) AND (${newWords.join(" ")})`;
-            }
-            else {
-                for (let i = 0; i < values.length; i++) {
-                    const mod = "_t:";
-                    const newWords: string[] = [];
-                    const oldWords = values[i].split(" ");
-                    oldWords.forEach((word, i) => i === 0 ? newWords.push(key + mod + word) : newWords.push("AND " + key + mod + word));
-                    const v = "(" + newWords.join(" ") + ")";
-                    if (i === 0) {
-                        query = `(${query}) AND (${v}` + (values.length === 1 ? ")" : "");
-                    }
-                    else query = query + " OR " + v + (i === values.length - 1 ? ")" : "");
-                }
-            }
-        }
-
-        return query.replace(/-\s+/g, '');
-    }
-
     @action
     filterDocsByType(docs: Doc[]) {
         const finalDocs: Doc[] = [];
@@ -340,7 +282,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             this._results[index][1].push(...hlights);
                             this._results[index][2].push(...line);
                         }
-
                     }));
 
                     this._curRequest = undefined;
@@ -360,37 +301,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         return this._lockPromise;
     }
 
-    startDragCollection = async () => {
-        const res = await this.getAllResults(this.getFinalQuery(StrCast(this.layoutDoc._searchString)));
-        const filtered = this.filterDocsByType(res.docs);
-        const docs = filtered.map(doc => Doc.GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeDelegate(doc) : Doc.MakeAlias(doc));
-        let x = 0;
-        let y = 0;
-        for (const doc of docs.map(d => Doc.Layout(d))) {
-            doc.x = x;
-            doc.y = y;
-            const size = 200;
-            const aspect = Doc.NativeHeight(doc) / (Doc.NativeWidth(doc) || 1);
-            if (aspect > 1) {
-                doc._height = size;
-                doc._width = size / aspect;
-            } else if (aspect > 0) {
-                doc._width = size;
-                doc._height = size * aspect;
-            } else {
-                doc._width = size;
-                doc._height = size;
-            }
-            x += 250;
-            if (x > 1000) {
-                x = 0;
-                y += 300;
-            }
-        }
-        const headers = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).map(h => { const v = h[Copy](); v.color = "#f1efeb"; return v; });
-        return Docs.Create.SchemaDocument(headers, DocListCast(this.dataDoc[this.fieldKey]), { _autoHeight: true, _viewType: CollectionViewType.Schema, title: StrCast(this.layoutDoc._searchString) });
-    }
-
     @action.bound
     openSearch(e: React.SyntheticEvent) {
         e.stopPropagation();
@@ -479,6 +389,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     render() {
         const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
+
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
                 <div className="searchBox-bar" style={{ background: SearchBox.Instance._undoBackground }}>
@@ -487,7 +398,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             {`${Doc.CurrentUserEmail}`}
                             <div className="searchBox-logoff" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
                                 Logoff
-                        </div>
+                            </div>
                         </div>
                         <div className="searchBox-lozenge" onClick={() => DocServer.UPDATE_SERVER_CACHE()}>
                             {`UI project`}
@@ -499,10 +410,10 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             </select>
                             <div className="searchBox-dashboards" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}>
                                 New
-                        </div>
+                            </div>
                             <div className="searchBox-dashboards" onClick={undoBatch(() => CurrentUserUtils.snapshotDashboard(Doc.UserDoc()))}>
                                 Snapshot
-                        </div>
+                            </div>
                         </div>
                     </div>
                     <div className="searchBox-query" >
@@ -511,24 +422,12 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                             style={{ padding: 1, paddingLeft: 20, paddingRight: 60, color: "black", height: 20, width: 250 }} />
                         <div style={{ display: "flex", alignItems: "center" }}>
                             <div style={{ position: "absolute", left: 10 }}>
-                                <Tooltip title={<div className="dash-tooltip" >drag search results as collection</div>}>
-                                    <div ref={this.collectionRef}><FontAwesomeIcon onPointerDown={SetupDrag(this.collectionRef, () => StrCast(this.layoutDoc._searchString) ? this.startDragCollection() : undefined)} icon={"search"} size="lg"
-                                        style={{ cursor: "hand", color: "black", padding: 1, position: "relative" }} /></div>
-                                </Tooltip>
+                                <FontAwesomeIcon icon={"search"} size="lg"
+                                    style={{ color: "black", padding: 1, position: "relative" }} />
                             </div>
                             <div style={{ position: "absolute", left: Doc.UserDoc().noviceMode ? 220 : 200, width: 30, zIndex: 9000, color: "grey", background: "white", }}>
                                 {`${this._results.length}` + " of " + `${this.realTotalResults}`}
                             </div>
-                            {Doc.UserDoc().noviceMode ? (null) : <div style={{ cursor: "default", left: 235, position: "absolute", }}>
-                                <Tooltip title={<div className="dash-tooltip" >only display documents matching search</div>} >
-                                    <div>
-                                        <FontAwesomeIcon icon={"filter"} size="lg"
-                                            style={{ cursor: "hand", padding: 1, backgroundColor: this.filter ? "white" : "lightgray", color: this.filter ? "black" : "white" }}
-                                            onPointerDown={e => { e.stopPropagation(); SetupDrag(this.collectionRef, () => this.layoutDoc._searchString ? this.startDragCollection() : undefined); }}
-                                            onClick={action(() => this.setSearchFilter(this.currentSelectedCollection, this.filter ? undefined : this.docsforfilter))} />
-                                    </div>
-                                </Tooltip>
-                            </div>}
                         </div>
                     </div >
                 </div >
-- 
cgit v1.2.3-70-g09d2


From fc1559fd74bde212f418b27806b68a76748153ad Mon Sep 17 00:00:00 2001
From: dg314 <david_grossman@brown.edu>
Date: Thu, 29 Jul 2021 15:12:03 -0400
Subject: search panel updates

---
 src/client/util/CurrentUserUtils.ts    |  11 +-
 src/client/views/MainView.tsx          |   6 +-
 src/client/views/search/SearchBox.scss | 173 ++++--------
 src/client/views/search/SearchBox.tsx  | 491 +++++++++++++++------------------
 4 files changed, 291 insertions(+), 390 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 596ccd9a6..31384da3b 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -947,17 +947,12 @@ export class CurrentUserUtils {
 
     // Search sidebar is where searches within the document are performed
     static setupSearchSidebar(doc: Doc) {
-        if (doc.mySearchPanelDoc === undefined) {
-            doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({
-                _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
+        if (doc.mySearchPanel === undefined) {
+            doc.mySearchPanel = new PrefetchProxy(Docs.Create.SearchDocument({
+                backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
                 childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
             })) as any as Doc;
         }
-        if (doc.mySearchPanel === undefined) {
-            const searchPanelDoc = Cast(doc.mySearchPanelDoc, Doc, null);
-            //const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
-            doc.mySearchPanel = new PrefetchProxy(Docs.Create.StackingDocument([searchPanelDoc], { title: "Search", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true }));
-        }
     }
 
     static setupClickEditorTemplates(doc: Doc) {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index bc9c6f4d2..0d957518b 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -178,12 +178,12 @@ export class MainView extends React.Component {
         const targets = document.elementsFromPoint(e.x, e.y);
         if (targets.length) {
             const targClass = targets[0].className.toString();
-            if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
+            /*if (SearchBox.Instance._resultsOpen) {
                 const check = targets.some((thing) =>
                 (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
                     thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
-            }
+            }*/
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
             !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
         }
@@ -192,7 +192,7 @@ export class MainView extends React.Component {
     initEventListeners = () => {
         window.addEventListener("drop", e => e.preventDefault(), false);  // prevent default behavior of navigating to a new web page
         window.addEventListener("dragover", e => e.preventDefault(), false);
-        document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
+        //document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
         document.addEventListener("pointerdown", this.globalPointerDown);
         document.addEventListener("click", (e: MouseEvent) => {
             if (!e.cancelBubble) {
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 4f5b7e41a..f8e994da7 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -2,141 +2,84 @@
 @import "./NaviconButton.scss";
 
 .searchBox-container {
-    display: flex;
-    flex-direction: column;
     width: 100%;
     height: 100%;
-    position: relative;
     font-size: 10px;
     line-height: 1;
-    overflow-y: auto;
-    overflow-x: visible;
-    background: lightgrey;
-    overflow: visible;
+    background: none;
     z-index: 1000;
+    padding: 0px;
+    cursor: default;
 
     .searchBox-bar {
-        height: $searchpanel-height;
+        width: 100%;
+        height: 35px;
         display: flex;
         justify-content: center;
         align-items: center;
-        background-color: black;
+        background-color: none;
+        padding: 5px;
 
-        .searchBox-lozenges {
-            position: absolute;
-            left: 15;
-            display: flex;
-
-            .searchBox-lozenge-user,
-            .searchBox-lozenge-dashboard,
-            .searchBox-lozenge {
-                height: 18px;
-                padding: 4px;
-                margin-right: 5px;
-                display: flex;
-                align-items: center;
-                border: grey 1px solid;
-                .searchBox-logoff,
-                .searchBox-dashboards {
-                    border-radius: 3px;
-                    background: olivedrab;
-                    color: white;
-                    display: none;
-                    margin-left: 5px;
-                    padding: 1px 2px 1px 2px;
-                    cursor: pointer;
-                }
-                .searchBox-logoff {
-                    background: red;
-                }
-
-                .searchBox-dashSelect{
-                    border: none;
-                    background-color: transparent;
+        .searchBox-type {
+            display: block;
+            width: 50px;
+            outline: none;
+            padding: 1px 5px 1px 5px;
+            color: black;
+            height: 25px;
+            border: 1px solid black;
+        }
 
-                    &:hover {
-                        cursor: pointer;
-                    }
-                }
-            }
-            .searchBox-lozenge-user:hover {
-                .searchBox-logoff {
-                    display:inline-block;
-                }
-            }
-            .searchBox-lozenge-dashboard:hover {
-                .searchBox-dashboards {
-                    display:inline-block;
-                }
-            }
+        .searchBox-input {
+            display: block;
+            width: calc(100% - 50px);
+            outline: none;
+            padding: 1px 5px 1px 5px;
+            color: black;
+            height: 25px;
+            border: 1px solid black;
         }
-        .searchBox-query {
-            position: relative;
+    }
+
+    .searchBox-results-container {
+        display: flex;
+        flex-direction: column;
+        width: 100%;
+        height: 100%;
+        justify-content: "center";
+    
+        .searchBox-results-count {
             display: flex;
-            width: 450;
+            color: gray;
+            margin-left: 5px;
         }
-        .searchBox-barChild {
+    
+        .searchBox-results-scroll-view {
+            margin-top: 10px;
+            display: inline-block;
+            width: 100%;
+            height: calc(100% - 55px);
+            overflow-y: scroll;
 
-            &.searchBox-collection {
-                flex: 0 1 auto;
-                margin-left: 2px;
-                margin-right: 2px
-            }
+            .searchBox-results-scroll-view-result {
+                display: inline-block;
+                vertical-align: middle;
+                width: 100%;
+                height: 40px;
+                cursor: pointer;
+                font-size: 15px;
+                padding: 10px;
 
-            &.searchBox-input {
-                margin:5px;
-                border-radius:20px;
-                border:black;    
-                display: block;
-                width: 130px;
-                -webkit-transition: width 0.4s;
-                transition: width 0.4s;
-                align-self: stretch;
-                outline:none;
-                &:focus {
-                    width: 500px;
-                    outline:none;
+                &.searchBox-results-scroll-view-result-selected {
+                    background: gray;
                 }
-            }
-            &.searchBox-filter {
-                align-self: stretch;
-                button{
-                    transform:none;
-                    &:hover {
-                        transform: none;
-                    }
-                }
-            }
 
-            &.searchBox-submit {
-                margin-left: 2px;
-                margin-right: 2px
-            }
-
-            &.searchBox-close {
-                color: $light-color;
-                max-height: $searchpanel-height;
+                .titletitle {
+                    display: relative;
+                    float: left;
+                    left: 50px;
+                }
             }
         }
-    }   
-}
-
-.searchBox-results {
-    display: flex;
-    flex-direction: column;
-    top: 300px;
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-    overflow: visible;
-
-    .no-result {
-        width: 500px;
-        background: $light-color-secondary;
-        padding: 10px;
-        height: 50px;
-        text-transform: uppercase;
-        text-align: left;
-        font-weight: bold;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index cc4590969..374a754bf 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -3,7 +3,7 @@ import { Tooltip } from '@material-ui/core';
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym, FieldsSym } from '../../../fields/Doc';
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Copy, Id, ToString } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
@@ -26,6 +26,9 @@ import "./SearchBox.scss";
 import { undoBatch } from "../../util/UndoManager";
 import { DocServer } from "../../DocServer";
 import { MainView } from "../MainView";
+import { DocumentManager } from "../../util/DocumentManager";
+import { CollectionSchemaBooleanCell } from "../collections/CollectionSchemaCells";
+import { transpileModule } from "typescript";
 
 export const searchSchema = createSchema({ Document: Doc });
 
@@ -38,33 +41,18 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     public static Instance: SearchBox;
 
     private _allIcons: string[] = [DocumentType.INK, DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB];
-    private _numResultsPerPage = 500;
-    private _numTotalResults = -1;
-    private _endIndex = -1;
-    private _lockPromise?: Promise<void>;
     private _resultsSet = new Map<Doc, number>();
     private _inputRef = React.createRef<HTMLInputElement>();
-    private _maxSearchIndex: number = 0;
-    private _curRequest?: Promise<any> = undefined;
     private _disposers: { [name: string]: IReactionDisposer } = {};
     private _blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
 
-    private docsforfilter: Doc[] | undefined = [];
-    private realTotalResults: number = 0;
-    private newsearchstring = "";
-
-    @observable _undoBackground: string | undefined = "";
+    @observable _searchString = "";
+    @observable _docTypeString = "all";
     @observable _icons: string[] = this._allIcons;
     @observable _results: [Doc, string[], string[]][] = [];
-    @observable _visibleElements: JSX.Element[] = [];
-    @observable _visibleDocuments: Doc[] = [];
+    @observable _selectedResult: Doc | undefined = undefined;
     @observable _deletedDocsStatus: boolean = false;
     @observable _onlyAliases: boolean = true;
-    @observable _searchbarOpen = false;
-    @observable _noResults = "";
-    @observable _pageStart = 0;
-    @observable open = false;
-    @observable children = 0;
     @computed get filter() { return this._results?.length && (this.currentSelectedCollection?.props.Document._searchFilterDocs || this.currentSelectedCollection?.props.Document._docFilters); }
 
     constructor(props: any) {
@@ -76,8 +64,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         if (this._inputRef.current) {
             this._inputRef.current.focus();
         }
-        this._disposers.filters = reaction(() => this.props.Document._docFilters,
-            (filters: any) => this.setSearchFilter(this.currentSelectedCollection, !this.filter ? undefined : this.docsforfilter));
     });
 
     componentWillUnmount() {
@@ -86,32 +72,25 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @computed get currentSelectedCollection() { return CollectionDockingView.Instance; }
 
-    onChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
-        this.newsearchstring = e.target.value;
-        if (e.target.value === "") {
-            console.log("Reset start");
-            this.docsforfilter = undefined;
-            this.setSearchFilter(this.currentSelectedCollection, undefined);
-            this.resetSearch(false);
-
-            this.open = false;
-            this._results = [];
-            this._resultsSet.clear();
-            this._visibleElements = [];
-            this._numTotalResults = -1;
-            this._endIndex = -1;
-            this._curRequest = undefined;
-            this._maxSearchIndex = 0;
-        }
+    onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
+        this._searchString = e.target.value;
+        this.submitSearch();
     });
 
-    enter = action((e: React.KeyboardEvent | undefined) => {
+    onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
+        this._docTypeString = e.target.value;
+        this.submitSearch();
+    });
+
+    /*enter = action((e: React.KeyboardEvent | undefined) => {
         if (!e || e.key === "Enter") {
-            this.layoutDoc._searchString = this.newsearchstring;
-            this._pageStart = 0;
-            this.open = true;
             this.submitSearch();
         }
+    });*/
+
+    onResultClick = action((doc: Doc) => {
+        this.selectElement(doc);
+        this._selectedResult = doc;
     });
 
     @action
@@ -126,21 +105,6 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         return finalDocs;
     }
 
-    static async foreachRecursiveDocAsync(docs: Doc[], func: (doc: Doc) => void) {
-        let newarray: Doc[] = [];
-        while (docs.length > 0) {
-            newarray = [];
-            await Promise.all(docs.filter(d => d).map(async d => {
-                const fieldKey = Doc.LayoutFieldKey(d);
-                const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
-                const data = d[annos ? fieldKey + "-annotations" : fieldKey];
-                const docs = await DocListCastAsync(data);
-                docs && newarray.push(...docs);
-                func(d);
-            }));
-            docs = newarray;
-        }
-    }
     static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
         let newarray: Doc[] = [];
         while (docs.length > 0) {
@@ -172,15 +136,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             });
 
             this._results = found;
-            this.docsforfilter = this._results.map(r => r[0]);
-            this.setSearchFilter(selectedCollection, this.filter && found.length ? this.docsforfilter : undefined);
-            this._numTotalResults = found.length;
-            this.realTotalResults = found.length;
         }
-        else {
-            this._noResults = "No collection selected :(";
-        }
-
     }
 
     static documentKeys(doc: Doc) {
@@ -197,246 +153,253 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     @action
     submitSearch = async () => {
-        this.resetSearch(false);
-
-        //this.props.Document._docFilters = new List();
-        this._noResults = "";
+        this.resetSearch();
 
         this.dataDoc[this.fieldKey] = new List<Doc>([]);
-        this.children = 0;
-        let query = StrCast(this.layoutDoc._searchString);
+        let query = StrCast(this._searchString);
         Doc.SetSearchQuery(query);
         this._results = [];
         this._resultsSet.clear();
-        this._visibleElements = [];
-        this._visibleDocuments = [];
 
         if (query) {
-            this._endIndex = 12;
-            this._maxSearchIndex = 0;
-            this._numTotalResults = -1;
             this.searchCollection(query);
-            runInAction(() => {
-                this.open = this._searchbarOpen = true;
-                this.resultsScrolled();
-            });
         }
     }
 
-    getAllResults = async (query: string) => {
-        return SearchUtil.Search(query, true, { fq: this.filterQuery, start: 0, rows: 10000000 });
-    }
+    resetSearch = action(() => {
+        this._results.forEach(result => {
+            Doc.UnBrushDoc(result[0]);
+            Doc.ClearSearchMatches();
+        });
+    });
 
-    private get filterQuery() {
-        const baseExpr = "NOT system_b:true";
-        const authorExpr = undefined;
-        const includeDeleted = this._deletedDocsStatus ? "" : " NOT deleted_b:true";
-        const typeExpr = this._onlyAliases ? "NOT {!join from=id to=proto_i}type_t:*" : `(type_t:* OR {!join from=id to=proto_i}type_t:*) ${this._blockedTypes.map(type => `NOT ({!join from=id to=proto_i}type_t:${type}) AND NOT type_t:${type}`).join(" AND ")}`;
-        // fq: type_t:collection OR {!join from=id to=proto_i}type_t:collection   q:text_t:hello
-        return [baseExpr, authorExpr, includeDeleted, typeExpr].filter(q => q).join(" AND ").replace(/AND $/, "");
+    selectElement = async (doc: Doc) => {
+        await DocumentManager.Instance.jumpToDocument(doc, true); // documents open in new tab instead of on right    
     }
 
-    @computed get primarySort() {
-        const suffixMap = (type: ColumnType) => {
-            switch (type) {
-                case ColumnType.Date: return "_d";
-                case ColumnType.String: return "_t";
-                case ColumnType.Boolean: return "_b";
-                case ColumnType.Number: return "_n";
+    render() {
+        const results = this._results.map(result => {
+            var className = "searchBox-results-scroll-view-result";
+
+            if (this._selectedResult == result[0]) {
+                className += " searchBox-results-scroll-view-result-selected"
             }
-        };
-        const headers = Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []);
-        return headers.reduce((p: Opt<string>, header: SchemaHeaderField) => p || (header.desc !== undefined && suffixMap(header.type) ? (header.heading + suffixMap(header.type) + (header.desc ? " desc" : " asc")) : undefined), undefined);
-    }
 
-    searchDatabase = async (query: string) => {
-        this._lockPromise && (await this._lockPromise);
-        this._lockPromise = new Promise(async res => {
-            while (this._results.length <= this._endIndex && (this._numTotalResults === -1 || this._maxSearchIndex < this._numTotalResults)) {
-                this._curRequest = SearchUtil.Search(query, true, { onlyAliases: true, allowAliases: true, /*sort: this.primarySort,*/ fq: this.filterQuery, start: 0, rows: this._numResultsPerPage, hl: "on", "hl.fl": "*", }).then(action(async (res: SearchUtil.DocSearchResult) => {
-                    // happens at the beginning
-                    this.realTotalResults = res.numFound <= 0 ? 0 : res.numFound;
-                    if (res.numFound !== this._numTotalResults && this._numTotalResults === -1) {
-                        this._numTotalResults = res.numFound;
-                    }
-                    const highlighting = res.highlighting || {};
-                    const highlightList = res.docs.map(doc => highlighting[doc[Id]]);
-                    const lines = new Map<string, string[]>();
-                    res.docs.map((doc, i) => lines.set(doc[Id], res.lines[i]));
-                    const docs = res.docs;
-                    const highlights: typeof res.highlighting = {};
-                    docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]);
-                    const filteredDocs = this.filterDocsByType(docs);
-
-                    runInAction(() => filteredDocs.forEach((doc, i) => {
-                        const index = this._resultsSet.get(doc);
-                        const highlight = highlights[doc[Id]];
-                        const line = lines.get(doc[Id]) || [];
-                        const hlights = highlight ? Object.keys(highlight).map(key => key.substring(0, key.length - 2)).filter(k => k) : [];
-                        // if (this.findCommonElements(hlights)) {
-                        // }
-                        if (index === undefined) {
-                            this._resultsSet.set(doc, this._results.length);
-                            this._results.push([doc, hlights, line]);
-                        } else {
-                            this._results[index][1].push(...hlights);
-                            this._results[index][2].push(...line);
-                        }
-                    }));
-
-                    this._curRequest = undefined;
-                }));
-                this._maxSearchIndex += this._numResultsPerPage;
-
-                await this._curRequest;
+            if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
+                return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="titletitle">{result[0].title}</div></div>)
             }
 
-            this.resultsScrolled();
+            return null;
+        })
 
-            const selectedCollection = this.currentSelectedCollection;//SelectionManager.SelectedDocuments()[0];
-            this.docsforfilter = this._results.map(r => r[0]);
-            this.setSearchFilter(selectedCollection, this.filter ? this.docsforfilter : undefined);
-            res();
-        });
-        return this._lockPromise;
+        results.filter(result => result)
+
+        return (
+            <div style={{ pointerEvents: "all" }} className="searchBox-container">
+                <div className="searchBox-bar">
+                    <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
+                        <option value="all">All</option>
+                        <option value="rtf">Text</option>
+                        <option value="img">Image</option>
+                        <option value="pdf">PDF</option>
+                    </select>
+                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" ref={this._inputRef} className="searchBox-input" />
+                </div >
+                <div className="searchBox-results-container">
+                    <div className="searchBox-results-count">
+                        {`${results.length}` + " result" + (results.length == 1 ? "" : "s")}
+                    </div>
+                    <div className="searchBox-results-scroll-view">
+                        {results}
+                    </div>
+                </div>
+            </div >
+        );
     }
+}
+
+
+
+/*
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tooltip } from '@material-ui/core';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym, FieldsSym } from '../../../fields/Doc';
+import { documentSchema } from "../../../fields/documentSchemas";
+import { Copy, Id, ToString } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from "../../documents/DocumentTypes";
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
+import { SetupDrag } from '../../util/DragManager';
+import { SearchUtil } from '../../util/SearchUtil';
+import { Transform } from '../../util/Transform';
+import { CollectionDockingView } from "../collections/CollectionDockingView";
+import { CollectionSchemaView, ColumnType } from "../collections/CollectionSchemaView";
+import { CollectionViewType } from '../collections/CollectionView';
+import { ViewBoxBaseComponent } from "../DocComponent";
+import { FieldView, FieldViewProps } from '../nodes/FieldView';
+import "./SearchBox.scss";
+import { undoBatch } from "../../util/UndoManager";
+import { DocServer } from "../../DocServer";
+import { MainView } from "../MainView";
+import { SelectionManager } from "../../util/SelectionManager";
+import { CollectionSchemaBooleanCell } from "../collections/CollectionSchemaCells";
+import { transpileModule } from "typescript";
+import { DocumentManager } from "../../util/DocumentManager";
+
+export const searchSchema = createSchema({ Document: Doc });
+
+type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
+const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
+
+@observer
+export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
+    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
+    public static Instance: SearchBox;
+
+    @observable _searchString = "";
+    @observable _docTypeString = "all";
+    @observable _results: [Doc, string[], string[]][] = [];
+    @observable _selectedResult: Doc | undefined = undefined;
+    @observable _deletedDocsStatus: boolean = false;
+    @observable _onlyAliases: boolean = true;
 
-    @action.bound
-    openSearch(e: React.SyntheticEvent) {
-        e.stopPropagation();
-        this._results.forEach(result => Doc.BrushDoc(result[0]));
+    constructor(props: any) {
+        super(props);
+        SearchBox.Instance = this;
     }
 
-    resetSearch = action((close: boolean) => {
-        this._results.forEach(result => {
-            Doc.UnBrushDoc(result[0]);
-            Doc.ClearSearchMatches();
-        });
-        close && (this.open = this._searchbarOpen = false);
+    onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
+        this._searchString = e.target.value;
+        this.submitSearch();
     });
 
-    @action.bound
-    closeResults() {
-        this._results = [];
-        this._resultsSet.clear();
-        this._visibleElements = [];
-        this._visibleDocuments = [];
-        this._numTotalResults = -1;
-        this._endIndex = -1;
-        this._curRequest = undefined;
-    }
+    onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
+        this._docTypeString = e.target.value;
+        this.submitSearch();
+    });
 
-    @action
-    resultsScrolled = (e?: React.UIEvent<HTMLDivElement>) => {
-        this._endIndex = 30;
-        const headers = new Set<string>(["title", "author", "text", "type", "data", "*lastModified", "context"]);
+    onResultClick = action((doc: Doc) => {
+        this.selectElement(doc);
+        this._selectedResult = doc;
+    });
 
-        if (this._numTotalResults <= this._maxSearchIndex) {
-            this._numTotalResults = this._results.length;
+    static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
+        const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
+        let newarray: Doc[] = [];
+        while (docs.length > 0) {
+            newarray = [];
+            docs.filter(d => d).forEach(d => {
+                const dtype = StrCast(d.type, "string") as DocumentType;
+                if (dtype && !blockedTypes.includes(dtype)) {
+                    const fieldKey = Doc.LayoutFieldKey(d);
+                    const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
+                    const data = d[annos ? fieldKey + "-annotations" : fieldKey];
+                    data && newarray.push(...DocListCast(data));
+                    func(d);
+                }
+            });
+            docs = newarray;
         }
+    }
 
-        // only hit right at the beginning
-        // visibleElements is all of the elements (even the ones you can't see)
-        if (this._visibleElements.length !== this._numTotalResults) {
-            // undefined until a searchitem is put in there
-            this._visibleElements = Array<JSX.Element>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
-            this._visibleDocuments = Array<Doc>(this._numTotalResults === -1 ? 0 : this._numTotalResults);
-        }
-        let max = this._numResultsPerPage;
-        max > this._results.length ? max = this._results.length : console.log("");
-        for (let i = this._pageStart; i < max; i++) {
-            //if the index is out of the window then put a placeholder in
-            //should ones that have already been found get set to placeholders?
-
-            let result: [Doc, string[], string[]] | undefined = undefined;
-
-            result = this._results[i];
-            if (result) {
-                const highlights = Array.from([...Array.from(new Set(result[1]).values())]);
-                const lines = new List<string>(result[2]);
-                highlights.forEach((item) => headers.add(item));
-                Doc.SetSearchMatch(result[0], { searchMatch: 1 });
-                if (i < this._visibleDocuments.length) {
-                    this._visibleDocuments[i] = result[0];
-                    Doc.BrushDoc(result[0]);
-                    Doc.AddDocToList(this.dataDoc, this.props.fieldKey, result[0]);
-                    this.children++;
+    @action
+    searchCollection(query: string) {
+        const selectedCollection = CollectionDockingView.Instance;
+        query = query.toLowerCase();
+
+        if (selectedCollection !== undefined) {
+            console.log("hello111")
+            // this._currentSelectedCollection = selectedCollection;
+            const docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]);
+            const found: [Doc, string[], string[]][] = [];
+            SearchBox.foreachRecursiveDoc(docs, (doc: Doc) => {
+                console.log("HELLO")
+                if (this._docTypeString == "all" || this._docTypeString == doc.type) {
+                    const hlights = new Set<string>();
+                    SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
+                    Array.from(hlights.keys()).length > 0 && found.push([doc, Array.from(hlights.keys()), []]);
                 }
-            }
-        }
-        if (this.props.Document._schemaHeaders === undefined) {
-            this.props.Document._schemaHeaders = new List<SchemaHeaderField>([new SchemaHeaderField("title", "#f1efeb")]);
-        }
-        if (this._maxSearchIndex >= this._numTotalResults) {
-            this._visibleElements.length = this._results.length;
-            this._visibleDocuments.length = this._results.length;
+            });
+
+            this._results = found;
+            //this.setSearchFilter(selectedCollection, this.filter && found.length ? this._docsforfilter : undefined);
         }
     }
 
-    getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
-    panelHeight = () => this.props.PanelHeight();
-    selectElement = (doc: Doc) => { /* this.gotoDocument(this.childDocs.indexOf(doc), NumCasst(this.layoutDoc._itemIndex)); */ };
-    returnHeight = () => NumCast(this.layoutDoc._height);
-    returnLength = () => Math.min(window.innerWidth, 51 + 205 * Cast(this.props.Document._schemaHeaders, listSpec(SchemaHeaderField), []).length);
-
-    setSearchFilter = action((collectionView: { props: { Document: Doc } }, docsForFilter: Doc[] | undefined) => {
-        if (collectionView) {
-            const docFilters = Cast(this.props.Document._docFilters, listSpec("string"), null);
-            collectionView.props.Document._searchFilterDocs = docsForFilter?.length ? new List<Doc>(docsForFilter) : undefined;
-            collectionView.props.Document._docFilters = docsForFilter?.length && docFilters?.length ? new List<string>(docFilters) : undefined;
+    static documentKeys(doc: Doc) {
+        const keys: { [key: string]: boolean } = {};
+        // bcz: ugh.  this is untracked since otherwise a large collection of documents will blast the server for all their fields.
+        //  then as each document's fields come back, we update the documents _proxies.  Each time we do this, the whole schema will be
+        //  invalidated and re-rendered.   This workaround will inquire all of the document fields before the options button is clicked.
+        //  then by the time the options button is clicked, all of the fields should be in place.  If a new field is added while this menu
+        //  is displayed (unlikely) it won't show up until something else changes.
+        //TODO Types
+        Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false));
+        return Array.from(Object.keys(keys));
+    }
+
+    @action
+    submitSearch = async () => {
+        Doc.ClearSearchMatches();
+        this._results = [];
+
+        this.dataDoc[this.fieldKey] = new List<Doc>([]);
+        let query = StrCast(this._searchString);
+        Doc.SetSearchQuery(query);
+        this._results = [];
+
+        if (query) {
+            this.searchCollection(query);
         }
-    });
+    }
+
+    selectElement = async (doc: Doc) => {
+        await DocumentManager.Instance.jumpToDocument(doc, true); // documents open in new tab instead of on right
+    }
 
     render() {
-        const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
+        const results = this._results.map(result => {
+            var className = "searchBox-results-scroll-view-result";
+
+            if (this._selectedResult == result[0]) {
+                className += " searchBox-results-scroll-view-result-selected"
+            }
+
+            return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="titletitle">{result[0].title}</div></div>)
+        })
 
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
-                <div className="searchBox-bar" style={{ background: SearchBox.Instance._undoBackground }}>
-                    <div className="searchBox-query" >
-                        <input defaultValue={""} autoComplete="off" onChange={this.onChange} type="text" placeholder="Search..." id="search-input" ref={this._inputRef}
-                            className="searchBox-barChild searchBox-input" onKeyPress={this.enter}
-                            style={{ padding: 1, paddingLeft: 20, paddingRight: 60, color: "black", height: 20, width: 250 }} />
-                        <div style={{ display: "flex", alignItems: "center" }}>
-                            <div style={{ position: "absolute", left: 10 }}>
-                                <FontAwesomeIcon icon={"search"} size="lg"
-                                    style={{ color: "black", padding: 1, position: "relative" }} />
-                            </div>
-                            <div style={{ position: "absolute", left: Doc.UserDoc().noviceMode ? 220 : 200, width: 30, zIndex: 9000, color: "grey", background: "white", }}>
-                                {`${this._results.length}` + " of " + `${this.realTotalResults}`}
-                            </div>
-                        </div>
-                    </div >
+                <div className="searchBox-bar">
+                    <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
+                        <option value="all">All</option>
+                        <option value="rtf">Text</option>
+                        <option value="img">Img</option>
+                        <option value="pdf">PDF</option>
+                        <option value="video">Vid</option>
+                        <option value="audio">Aud</option>
+                        <option value="inks">Ink</option>
+                        <option value="col">Col</option>
+                    </select>
+                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" />
                 </div >
-                {!this._searchbarOpen ? (null) :
-                    <div style={{ zIndex: 20000, color: "black" }} ref={(r) => r?.focus()}>
-                        <div style={{ display: "flex", justifyContent: "center", }}>
-                            <div style={{ display: this.open ? "flex" : "none", overflow: "auto", position: "absolute" }}>
-                                <CollectionSchemaView {...this.props}
-                                    CollectionView={undefined}
-                                    addDocument={returnFalse}
-                                    Document={this.props.Document}
-                                    moveDocument={returnFalse}
-                                    removeDocument={returnFalse}
-                                    PanelHeight={this.open ? this.returnHeight : returnZero}
-                                    PanelWidth={this.open ? this.returnLength : returnZero}
-                                    scrollOverflow={length > window.innerWidth || this.children > 6 ? true : false}
-                                    focus={this.selectElement}
-                                    ScreenToLocalTransform={Transform.Identity}
-                                />
-                                <div style={{ position: "absolute", right: 5, bottom: 7, width: 15, height: 15, }}
-                                    onPointerDown={e => setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => {
-                                        this.props.Document._height = NumCast(this.props.Document._height) + delta[1];
-                                        return false;
-                                    }, returnFalse, emptyFunction)}
-                                >
-                                    <FontAwesomeIcon icon="grip-lines" size="lg" />
-                                </div>
-                            </div>
-                        </div>
+                <div className="searchBox-results-container">
+                    <div className="searchBox-results-count">
+                        {`${this._results.length}` + " result" + (this._results.length == 1 ? "" : "s")}
                     </div>
-                }
+                    <div className="searchBox-results-scroll-view">
+                        {results}
+                    </div>
+                </div>
             </div >
         );
     }
-}
\ No newline at end of file
+}*/
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From b33e45f1f839b3c6eaf1076e605abacd1bc6883c Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Thu, 29 Jul 2021 15:35:39 -0400
Subject: lots of updates!

---
 src/client/util/SettingsManager.tsx                |  79 ++++++--
 src/client/views/AntimodeMenu.scss                 |   2 +-
 src/client/views/MainView.scss                     |  27 ---
 src/client/views/MainView.tsx                      |  61 ++----
 src/client/views/_nodeModuleOverrides.scss         |  52 ++++-
 .../views/collections/CollectionDockingView.scss   |  98 +++++++---
 .../views/collections/CollectionDockingView.tsx    |   2 +-
 src/client/views/collections/TabDocView.scss       |  59 +++++-
 src/client/views/collections/TabDocView.tsx        | 107 +++++++----
 src/client/views/global/globalCssVariables.scss    |   4 +-
 src/client/views/global/globalEnums.tsx            |   4 +
 src/client/views/topbar/TopBar.scss                | 211 +++++++++++++++++++++
 src/client/views/topbar/TopBar.tsx                 |  58 ++++++
 src/fields/Doc.ts                                  |   6 +-
 14 files changed, 618 insertions(+), 152 deletions(-)
 create mode 100644 src/client/views/topbar/TopBar.scss
 create mode 100644 src/client/views/topbar/TopBar.tsx

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 777394b05..3987497b8 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -18,6 +18,12 @@ const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
+export enum ColorScheme {
+    Dark = "Dark",
+    Light = "Light",
+    System = "Match System"
+}
+
 @observer
 export class SettingsManager extends React.Component<{}> {
     public static Instance: SettingsManager;
@@ -32,7 +38,7 @@ export class SettingsManager extends React.Component<{}> {
     @observable activeTab = "Accounts";
 
     @computed get backgroundColor() { return Doc.UserDoc().activeCollectionBackground; }
-
+    @computed get colorScheme() { return Doc.UserDoc().colorScheme; }
 
     constructor(props: {}) {
         super(props);
@@ -69,6 +75,28 @@ export class SettingsManager extends React.Component<{}> {
         else DocServer.Control.makeEditable();
     });
 
+    @undoBatch
+    @action
+    changeColorScheme = action((e: React.ChangeEvent) => {
+        const scheme: ColorScheme = (e.currentTarget as any).value;
+        switch (scheme) {
+            case ColorScheme.Light:
+                Doc.UserDoc().colorScheme = ColorScheme.Light;
+                addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "#d3d3d3 !important" });
+                break;
+            case ColorScheme.Dark:
+                Doc.UserDoc().colorScheme = ColorScheme.Dark;
+                addStyleSheetRule(SettingsManager._settingsStyle, "lm_header", { background: "black !important" });
+                break;
+            case ColorScheme.System: default:
+                window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
+                    Doc.UserDoc().colorScheme = e.matches ? ColorScheme.Dark : ColorScheme.Light;
+                });
+                break;
+        }
+    });
+
+
     @computed get colorsContent() {
         const colorBox = (func: (color: ColorState) => void) => <SketchPicker onChange={func} color={StrCast(this.backgroundColor)}
             presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
@@ -90,8 +118,7 @@ export class SettingsManager extends React.Component<{}> {
             </Flyout>
         </div>;
 
-        const fontFamilies = ["Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"];
-        const fontSizes = ["7px", "8px", "9px", "10px", "12px", "14px", "16px", "18px", "20px", "24px", "32px", "48px", "72px"];
+        const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.System];
 
         return <div className="colors-content">
             <div className="preferences-color">
@@ -102,14 +129,11 @@ export class SettingsManager extends React.Component<{}> {
                 <div className="preferences-color-text">Border/Header Color</div>
                 {userColorFlyout}
             </div>
-            <div className="preferences-font">
-                <div className="preferences-font-text">Default Font</div>
-                <div className="preferences-font-controls">
-                    <select className="size-select" onChange={this.changeFontSize} value={StrCast(Doc.UserDoc().fontSize, "7px")}>
-                        {fontSizes.map(size => <option key={size} value={size} defaultValue={StrCast(Doc.UserDoc().fontSize)}> {size} </option>)}
-                    </select>
-                    <select className="font-select" onChange={this.changeFontFamily} value={StrCast(Doc.UserDoc().fontFamily, "Times New Roman")} >
-                        {fontFamilies.map(font => <option key={font} value={font} defaultValue={StrCast(Doc.UserDoc().fontFamily)}> {font} </option>)}
+            <div className="preferences-colorScheme">
+                <div className="preferences-color-text">Color Scheme</div>
+                <div className="preferences-color-controls">
+                    <select className="scheme-select" onChange={this.changeColorScheme} defaultValue={StrCast(Doc.UserDoc().colorScheme)}>
+                        {colorSchemes.map(scheme => <option key={scheme} value={scheme}> {scheme} </option>)}
                     </select>
                 </div>
             </div>
@@ -132,6 +156,16 @@ export class SettingsManager extends React.Component<{}> {
                     checked={BoolCast(Doc.UserDoc()._raiseWhenDragged)} />
                 <div className="preferences-check">Raise on drag</div>
             </div>
+            <div>
+                <input type="checkbox" onChange={e => Doc.UserDoc()._showLabel = !Doc.UserDoc()._showLabel}
+                    checked={BoolCast(Doc.UserDoc()._showLabel)} />
+                <div className="preferences-check">Show tool button labels</div>
+            </div>
+            <div>
+                <input type="checkbox" onChange={e => Doc.UserDoc()._showMenuLabel = !Doc.UserDoc()._showMenuLabel}
+                    checked={BoolCast(Doc.UserDoc()._showMenuLabel)} />
+                <div className="preferences-check">Show menu button labels</div>
+            </div>
         </div>;
     }
 
@@ -149,6 +183,27 @@ export class SettingsManager extends React.Component<{}> {
         </div>;
     }
 
+    @computed get textContent() {
+
+        const fontFamilies = ["Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text", "Roboto"];
+        const fontSizes = ["7px", "8px", "9px", "10px", "12px", "14px", "16px", "18px", "20px", "24px", "32px", "48px", "72px"];
+
+        return (
+            <div className="tab-content appearances-content">
+                <div className="preferences-font">
+                    <div className="preferences-font-text">Default Font</div>
+                    <div className="preferences-font-controls">
+                        <select className="size-select" onChange={this.changeFontSize} value={StrCast(Doc.UserDoc().fontSize, "7px")}>
+                            {fontSizes.map(size => <option key={size} value={size} defaultValue={StrCast(Doc.UserDoc().fontSize)}> {size} </option>)}
+                        </select>
+                        <select className="font-select" onChange={this.changeFontFamily} value={StrCast(Doc.UserDoc().fontFamily, "Times New Roman")} >
+                            {fontFamilies.map(font => <option key={font} value={font} defaultValue={StrCast(Doc.UserDoc().fontFamily)}> {font} </option>)}
+                        </select>
+                    </div>
+                </div>
+            </div>);
+    }
+
     @action
     changeVal = (e: React.ChangeEvent, pass: string) => {
         const value = (e.target as any).value;
@@ -228,7 +283,7 @@ export class SettingsManager extends React.Component<{}> {
         // { title: "Accounts", ele: this.accountsContent }, { title: "Preferences", ele: this.preferencesContent }];
 
         const tabs = [{ title: "Accounts", ele: this.accountsContent }, { title: "Modes", ele: this.modesContent },
-        { title: "Appearance", ele: this.appearanceContent }];
+        { title: "Appearance", ele: this.appearanceContent }, { title: "Text", ele: this.textContent }];
 
         return <div className="settings-interface">
             <div className="settings-panel">
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 2bac03af4..b509f9f54 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -6,7 +6,7 @@
     z-index: 10001;
     height: $antimodemenu-height;
     background: $dark-gray;
-    box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
+    // box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
     // border-radius: 0px 6px 6px 6px;
     z-index: 1001;
     display: flex;
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 07ca0257c..2069986ad 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -419,31 +419,4 @@
     display: block;
     width: 500px;
     height: 1000px;
-}
-
-.lm_drag_tab {
-    padding: 0;
-    width: 15px !important;
-    height: 15px !important;
-    position: relative !important;
-    display: inline-flex !important;
-    align-items: center;
-    top: 0 !important;
-    right: unset !important;
-    left: 0 !important;
-}
-.lm_close_tab {
-    padding: 0;
-    width: 15px !important;
-    height: 15px !important;
-    position: relative !important;
-    display: inline-flex !important;
-    align-items: center;
-    top: 0 !important;
-    right: unset !important;
-    left: 0 !important;
-}
-.lm_tab, .lm_tab_active {
-    display: flex !important;
-    padding-right: 0 !important;
 }
\ No newline at end of file
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index f34851b00..7d6bfbd40 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -63,6 +63,7 @@ import { PreviewCursor } from './PreviewCursor';
 import { PropertiesView } from './PropertiesView';
 import { SearchBox } from './search/SearchBox';
 import { DefaultStyleProvider, DashboardStyleProvider, StyleProp } from './StyleProvider';
+import { TopBar } from './topbar/TopBar';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -78,7 +79,7 @@ export class MainView extends React.Component {
     @observable private _sidebarContent: any = this.userDoc?.sidebar;
     @observable private _flyoutWidth: number = 0;
 
-    @computed private get topOffset() { return (CollectionMenu.Instance?.Pinned ? 35 : 0) + Number(SEARCH_PANEL_HEIGHT.replace("px", "")); }
+    @computed private get topOffset() { return Number(SEARCH_PANEL_HEIGHT.replace("px", "")); } //TODO remove
     @computed private get leftOffset() { return this.menuPanelWidth() - 2; }
     @computed private get userDoc() { return Doc.UserDoc(); }
     @computed private get darkScheme() { return BoolCast(CurrentUserUtils.ActiveDashboard?.darkScheme); }
@@ -180,8 +181,8 @@ export class MainView extends React.Component {
             const targClass = targets[0].className.toString();
             if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
                 const check = targets.some((thing) =>
-                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                    thing.className === "collectionSchema-header-menuOptions"));
+                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+                        thing.className === "collectionSchema-header-menuOptions"));
                 !check && SearchBox.Instance.resetSearch(true);
             }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
@@ -242,8 +243,9 @@ export class MainView extends React.Component {
     }
 
     getPWidth = () => this._panelWidth - this.propertiesWidth();
-    getPHeight = () => this._panelHeight;
+    getPHeight = () => this._panelHeight - (CollectionMenu.Instance?.Pinned ? 35 : 0);
     getContentsHeight = () => this._panelHeight;
+    getMenuPanelHeight = () => this._panelHeight + (CollectionMenu.Instance?.Pinned ? 35 : 0);
 
     @computed get mainDocView() {
         return <DocumentView key="main"
@@ -275,10 +277,12 @@ export class MainView extends React.Component {
 
     @computed get dockingContent() {
         return <div key="docking" className={`mainContent-div${this._flyoutWidth ? "-flyout" : ""}`} onDrop={e => { e.stopPropagation(); e.preventDefault(); }}
+            // style={{ minWidth: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`, width: `calc(100% - ${this._flyoutWidth + this.propertiesWidth()}px)` }}>
+            // FIXME update with property panel width
             style={{
                 minWidth: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`,
                 transform: LightboxView.LightboxDoc ? "scale(0.0001)" : undefined,
-                width: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`
+                //TODO:glr width: `calc(100% - ${this._flyoutWidth + this.menuPanelWidth() + this.propertiesWidth()}px)`
             }}>
             {!this.mainContainer ? (null) : this.mainDocView}
         </div>;
@@ -358,7 +362,7 @@ export class MainView extends React.Component {
                 removeDocument={returnFalse}
                 ScreenToLocalTransform={this.sidebarScreenToLocal}
                 PanelWidth={this.menuPanelWidth}
-                PanelHeight={this.getContentsHeight}
+                PanelHeight={this.getMenuPanelHeight}
                 renderDepth={0}
                 docViewPath={returnEmptyDoclist}
                 focus={DocUtils.DefaultFocus}
@@ -405,16 +409,19 @@ export class MainView extends React.Component {
             {this.menuPanel}
             <div key="inner" className={`mainView-innerContent${this.darkScheme ? "-dark" : ""}`}>
                 {this.flyout}
-                <div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined, }} onPointerDown={this.onFlyoutPointerDown} >
+                <div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined, left: this._flyoutWidth ? (this._flyoutWidth + this.menuPanelWidth() - 10) : -10 }} onPointerDown={this.onFlyoutPointerDown} >
                     <FontAwesomeIcon icon="chevron-left" color={this.darkScheme ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
                 </div>
+                <div className="mainView-innerContainer" style={{ width: `calc(100% - ${this.propertiesWidth() + this._flyoutWidth + this.menuPanelWidth()}px)` }}>
+                    <CollectionMenu />
 
-                {this.dockingContent}
+                    {this.dockingContent}
 
-                <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
-                    <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? "white" : "black"} size="sm" />
+                    <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
+                        <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? "white" : "black"} size="sm" />
+                    </div>
+                    {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.getContentsHeight()} />}
                 </div>
-                {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.getContentsHeight()} />}
             </div>
         </>;
     }
@@ -525,35 +532,8 @@ export class MainView extends React.Component {
 
     @computed get search() {
         TraceMobx();
-        return <div className="mainView-searchPanel">
-            <SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
-                DataDoc={CurrentUserUtils.MySearchPanelDoc}
-                fieldKey="data"
-                dropAction="move"
-                isSelected={returnTrue}
-                isContentActive={returnTrue}
-                select={returnTrue}
-                setHeight={returnFalse}
-                addDocument={undefined}
-                addDocTab={this.addDocTabFunc}
-                pinToPres={emptyFunction}
-                rootSelected={returnTrue}
-                styleProvider={DefaultStyleProvider}
-                layerProvider={undefined}
-                removeDocument={undefined}
-                ScreenToLocalTransform={Transform.Identity}
-                PanelWidth={this.getPWidth}
-                PanelHeight={this.getPHeight}
-                renderDepth={0}
-                focus={DocUtils.DefaultFocus}
-                docViewPath={returnEmptyDoclist}
-                whenChildContentsActiveChanged={emptyFunction}
-                bringToFront={emptyFunction}
-                docFilters={returnEmptyFilter}
-                docRangeFilters={returnEmptyFilter}
-                searchFilterDocs={returnEmptyDoclist}
-                ContainingCollectionView={undefined}
-                ContainingCollectionDoc={undefined} />
+        return <div className="mainView-topbar">
+            <TopBar />
         </div>;
     }
 
@@ -605,7 +585,6 @@ export class MainView extends React.Component {
             <GoogleAuthenticationManager />
             <DocumentDecorations boundsLeft={this.leftOffset} boundsTop={this.topOffset} />
             {this.search}
-            <CollectionMenu />
             {LinkDescriptionPopup.descriptionPopup ? <LinkDescriptionPopup /> : null}
             {DocumentLinksButton.LinkEditorDocView ? <LinkMenu docView={DocumentLinksButton.LinkEditorDocView} changeFlyout={emptyFunction} /> : (null)}
             {LinkDocPreview.LinkInfo ? <LinkDocPreview {...LinkDocPreview.LinkInfo} /> : (null)}
diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss
index 56346b68b..cb59489c0 100644
--- a/src/client/views/_nodeModuleOverrides.scss
+++ b/src/client/views/_nodeModuleOverrides.scss
@@ -1,8 +1,49 @@
+@import "./global/globalCssVariables";
 // this file is for overriding all the css from installed node modules
 
 // goldenlayout stuff
 div .lm_header {
     background: $dark-gray;
+    overflow: hidden;
+}
+
+/* Width */
+.lm_header::-webkit-scrollbar {
+    -webkit-appearance: none;
+    display: none;
+}
+
+/* Width */
+.lm_header:hover::-webkit-scrollbar {
+    -webkit-appearance: none;
+    display: block;
+    height: 0px;
+}
+
+/* Track */
+.lm_header:hover::-webkit-scrollbar-track {
+    -webkit-appearance: none;
+    display: none;
+}
+
+/* Handle */
+.lm_header:hover::-webkit-scrollbar-thumb {
+    -webkit-appearance: none;
+    background: $dark-gray;
+}
+
+/* Handle on hover */
+.lm_header:hover::-webkit-scrollbar-thumb:hover {
+    -webkit-appearance: none;
+    background: $dark-gray;
+}
+
+.lm_tabs {
+    display: flex;
+    position: absolute;
+    width: calc(100% - 60px);
+    overflow: scroll;
+    background: $dark-gray;
 }
 
 .lm_tab {
@@ -15,7 +56,16 @@ div .lm_header {
 }
 
 .lm_header .lm_controls {
-    right: 1em !important;
+    align-items: center;
+    position: absolute;
+    background-color: #000000;
+    border-radius: 5px;
+    display: flex;
+    top: 2px;
+    justify-content: space-evenly;
+    right: 2px;
+    height: 18px;
+    width: 65px;
 }
 
 // @TODO the ril__navgiation buttons in the img gallery are a lil messed up but I can't figure out
diff --git a/src/client/views/collections/CollectionDockingView.scss b/src/client/views/collections/CollectionDockingView.scss
index a054f0ae1..b8180fe24 100644
--- a/src/client/views/collections/CollectionDockingView.scss
+++ b/src/client/views/collections/CollectionDockingView.scss
@@ -1,40 +1,46 @@
-@import "../../views/global/globalCssVariables.scss";
+@import "../global/globalCssVariables.scss";
 
 
 .lm_title {
-    margin-top: 3px;
-    border-radius: 5px;
-    border: solid 0px dimgray;
-    border-width: 2px 2px 0px;
-    height: 20px;
-    transform: translate(0px, -3px);
+    -webkit-appearance: none;
+    display: inline-block;
+    align-self: center;
+    align-items: center;
+    height: 100%;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    background: transparent;
+    border: solid 0px transparent;
     cursor: grab;
+    color: $black;
 }
 
 .lm_title.focus-visible {
+    -webkit-appearance: none;
     cursor: text;
 }
 
 .lm_title_wrap {
     overflow: hidden;
-    height: 19px;
-    margin-top: -2px;
-    display: inline-block;
+    align-items: center;
+    align-self: center;
+    background: transparent;
+    width: max-content;
+    height: 100%;
+    display: flex;
 }
 
 .lm_active .lm_title {
-    border: solid 1px lightgray;
-}
-
-.lm_header .lm_tab .lm_close_tab {
-    position: absolute;
-    text-align: center;
+    -webkit-appearance: none;
+    // font-weight: 700;
 }
 
 .lm_header .lm_tab {
-    padding-right: 20px;
-    margin-top: -1px;
-    border-bottom: 1px black;
+    padding: 0px;
+    opacity: 0.7;
+    box-shadow: none;
+    height: 19px;
+    // border-bottom: 1px black;
 
     .collectionDockingView-gear {
         display: none;
@@ -42,9 +48,13 @@
 }
 
 .lm_header .lm_tab.lm_active {
-    padding-right: 20px;
-    margin-top: 1px;
-    border-bottom: unset;
+    padding: 0;
+    opacity: 1;
+    margin: 0;
+    box-shadow: none;
+    height: 22px;
+    margin-right: 2px;
+    // border-bottom: unset;
 
     .collectionDockingView-gear {
         display: inline-block;
@@ -55,6 +65,41 @@
     display: inline;
 }
 
+.lm_drag_tab {
+    padding: 0;
+    width: 15px !important;
+    height: 15px !important;
+    position: relative !important;
+    display: inline-flex !important;
+    align-items: center;
+    top: 0 !important;
+    right: unset !important;
+    left: 0 !important;
+}
+
+.lm_close_tab {
+    padding: 0;
+    align-self: center;
+    margin-right: 5px;
+    background-color: black;
+    border-radius: 3px;
+    opacity: 1 !important;
+    width: 15px !important;
+    height: 15px !important;
+    position: relative !important;
+    display: inline-flex !important;
+    align-items: center;
+    top: 0 !important;
+    right: unset !important;
+    left: 0 !important;
+}
+
+.lm_tab,
+.lm_tab_active {
+    display: flex !important;
+    padding-right: 0 !important;
+}
+
 .collectiondockingview-container {
     width: 100%;
     height: 100%;
@@ -82,16 +127,17 @@
     }
 
     .lm_content {
-        background: white;
+        background: $white;
     }
 
     .lm_controls>li {
-        opacity: 0.6;
-        transform: scale(1.2);
+        opacity: 1;
+        transform: scale(1);
     }
 
     .lm_controls .lm_popout {
-        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAUCAAAAABHICnvAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAHdElNRQfkCBsXMgbrEyzaAAAAT0lEQVQY02NgIAcIu8tgEW3/u4IDQ5B14/8LQlhFhckVFfCJjIyIOfP/QWpEZGSQJFS05s9fIPj3/z+YmseCTxS7CZS7DI+PsYcOjpAkDAA6H0KZxzDzlgAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMC0wOC0yN1QyMzo1MDowNi0wNDowMDvgVpQAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjAtMDgtMjdUMjM6NTA6MDYtMDQ6MDBKve4oAAAAAElFTkSuQmCC)
+        transform: rotate(45deg);
+        background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAAQUlEQVR4nHXOQQ4AMAgCQeT/f6aXpsGK3jSTuCVJAAr7iBdoAwCKd0nwfaAdHbYERw5b44+E8JoBjEYGMBq5gAYP3usUDu2IvoUAAAAASUVORK5CYII=);
     }
 
     .lm_maximised .lm_controls .lm_maximise {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 388f9a909..a8471f8e2 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -445,4 +445,4 @@ Scripting.addGlobal(function openInLightbox(doc: any) { LightboxView.AddDocTab(d
     "opens up document in a lightbox", "(doc: any)");
 Scripting.addGlobal(function openOnRight(doc: any) { return CollectionDockingView.AddSplit(doc, "right"); },
     "opens up document in tab on right side of the screen", "(doc: any)");
-Scripting.addGlobal(function useRightSplit(doc: any, shiftKey?: boolean) { CollectionDockingView.ReplaceTab(doc, "right", undefined, shiftKey); });
+Scripting.addGlobal(function useRightSplit(doc: any, shiftKey?: boolean) { CollectionDockingView.ReplaceTab(doc, "right", undefined, shiftKey); });
\ No newline at end of file
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 9acbc4f85..a963f1cb9 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -1,19 +1,62 @@
 input.lm_title:focus,
-input.lm_title
-{
+input.lm_title {
     max-width: unset !important;
+    outline: none;
     transition-delay: unset;
-    width: 100%;
+    width: max-content;
     cursor: text;
 }
+
 input.lm_title {
     transition-delay: 0.35s;
-    width: 100px;
+    width: max-content;
     cursor: pointer;
 }
-.tabDocView-drag {
-    margin: auto;
+
+.lm_iconWrap {
+    display: flex;
+    color: black;
+    width: 15px;
+    height: 15px;
+    align-items: center;
+    align-self: center;
+    justify-content: center;
+    margin: 3px;
+    border-radius: 20%;
+
+    .moreInfoDot {
+        background-color: white;
+        border-radius: 100%;
+        width: 3px;
+        height: 3px;
+        margin: 0.5px;
+    }
+}
+
+.ffMenu {
+    display: grid;
+    grid-auto-rows: 35px;
+    grid-auto-columns: auto auto auto auto auto;
+    right: 10px;
+    bottom: 50px;
+    position: absolute;
+    min-height: 35px;
+    height: max-content;
+    border: solid 2px black;
+    border-radius: 5px;
+    background-color: #bddbe6;
+    width: max-content;
+    min-width: 35px;
+
+    .ffMenuButton {
+        display: flex;
+        width: 35px;
+        height: 35px;
+        align-items: center;
+        justify-content: center;
+    }
 }
+
 .miniMap-hidden,
 .miniMap {
     position: absolute;
@@ -37,6 +80,7 @@ input.lm_title {
         }
     }
 }
+
 .miniMap-hidden {
     position: absolute;
     bottom: 0;
@@ -46,7 +90,8 @@ input.lm_title {
     transform: translate(20px, 20px) rotate(45deg);
     border-radius: 30px;
     padding: 2px;
-    > svg {
+
+    >svg {
         margin-top: 3px;
         transform: translate(0px, 7px);
     }
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 7e2f7811e..0e67bebd8 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -1,3 +1,4 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
 import 'golden-layout/src/css/goldenlayout-base.css';
@@ -9,9 +10,9 @@ import * as ReactDOM from 'react-dom';
 import { DataSym, Doc, DocListCast, DocListCastAsync, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
 import { Id } from '../../../fields/FieldSymbols';
 import { FieldId } from "../../../fields/RefField";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../fields/Types";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
 import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils";
+import { emptyFunction, lightOrDark, returnEmptyDoclist, returnFalse, returnTrue, setupMoveUpEvents, Utils } from "../../../Utils";
 import { DocServer } from "../../DocServer";
 import { DocUtils } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
@@ -24,15 +25,15 @@ import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from "../../util/UndoManager";
 import { LightboxView } from '../LightboxView';
 import { DocFocusOptions, DocumentView, DocumentViewProps } from "../nodes/DocumentView";
-import { FieldViewProps } from '../nodes/FieldView';
-import { PinProps, PresBox, PresMovement } from '../nodes/PresBox';
+import { PresBox, PinProps, PresMovement } from '../nodes/PresBox';
 import { DefaultLayerProvider, DefaultStyleProvider, StyleLayers, StyleProp } from '../StyleProvider';
 import { CollectionDockingView } from './CollectionDockingView';
 import { CollectionDockingViewMenu } from './CollectionDockingViewMenu';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
-import { CollectionViewType, CollectionView } from './CollectionView';
+import { CollectionView, CollectionViewType } from './CollectionView';
 import "./TabDocView.scss";
 import React = require("react");
+import Color = require('color');
 const _global = (window /* browser */ || global /* node */) as any;
 
 interface TabDocViewProps {
@@ -52,6 +53,14 @@ export class TabDocView extends React.Component<TabDocViewProps> {
 
     @computed get layoutDoc() { return this._document && Doc.Layout(this._document); }
     @computed get tabColor() { return StrCast(this._document?._backgroundColor, StrCast(this._document?.backgroundColor, DefaultStyleProvider(this._document, undefined, StyleProp.BackgroundColor))); }
+    @computed get tabTextColor() { return this._document?.type === DocumentType.PRES ? "black" : StrCast(this._document?._color, StrCast(this._document?.color, DefaultStyleProvider(this._document, undefined, StyleProp.Color))); }
+    // @computed get renderBounds() {
+    //     const bounds = this._document ? Cast(this._document._renderContentBounds, listSpec("number"), [0, 0, this.returnMiniSize(), this.returnMiniSize()]) : [0, 0, 0, 0];
+    //     const xbounds = bounds[2] - bounds[0];
+    //     const ybounds = bounds[3] - bounds[1];
+    //     const dim = Math.max(xbounds, ybounds);
+    //     return { l: bounds[0] + xbounds / 2 - dim / 2, t: bounds[1] + ybounds / 2 - dim / 2, cx: bounds[0] + xbounds / 2, cy: bounds[1] + ybounds / 2, dim };
+    // }
 
     get stack() { return (this.props as any).glContainer.parent.parent; }
     get tab() { return (this.props as any).glContainer.tab; }
@@ -65,15 +74,25 @@ export class TabDocView extends React.Component<TabDocViewProps> {
             tab.contentItem.config.fixed && (tab.contentItem.parent.config.fixed = true);
             tab.DashDoc = doc;
             CollectionDockingView.Instance.tabMap.add(tab);
-
+            const iconType: IconProp = Doc.toIcon(doc);
             // setup the title element and set its size according to the # of chars in the title.  Show the full title when clicked.
             const titleEle = tab.titleElement[0];
+            const iconWrap = document.createElement("div");
+            const closeWrap = document.createElement("div");
+
+
             titleEle.size = StrCast(doc.title).length + 3;
             titleEle.value = doc.title;
             titleEle.onchange = undoBatch(action((e: any) => {
                 titleEle.size = e.currentTarget.value.length + 3;
                 Doc.GetProto(doc).title = e.currentTarget.value;
             }));
+
+            const dragBtnDown = (e: React.PointerEvent) => {
+                setupMoveUpEvents(this, e, e => !e.defaultPrevented && DragManager.StartDocumentDrag([iconWrap], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY), returnFalse, emptyFunction);
+            };
+
+
             if (tab.element[0].children[1].children.length === 1) {
                 const toggle = document.createElement("div");
                 toggle.style.width = "10px";
@@ -83,18 +102,42 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                 toggle.style.borderTopRightRadius = "7px";
                 toggle.style.position = "relative";
                 toggle.style.display = "inline-block";
-                toggle.style.background = "gray";
-                toggle.style.borderLeft = "solid 1px black";
+                toggle.style.background = "transparent";
                 toggle.onclick = (e: MouseEvent) => {
                     if (tab.contentItem === tab.header.parent.getActiveContentItem()) {
                         tab.DashDoc.activeLayer = tab.DashDoc.activeLayer ? undefined : StyleLayers.Background;
                     }
                 };
-                tab.element[0].style.borderTopRightRadius = "8px";
-                tab.element[0].children[1].appendChild(toggle);
-                tab._disposers.layerDisposer = reaction(() =>
-                    ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
-                    ({ layer, color }) => toggle.style.background = !layer ? color : "dimgrey", { fireImmediately: true });
+                iconWrap.className = "lm_iconWrap";
+                iconWrap.id = "lm_iconWrap";
+                closeWrap.className = "lm_iconWrap";
+                closeWrap.id = "lm_closeWrap";
+                closeWrap.onclick = (e: MouseEvent) => {
+                    tab.header.parent.contentItem.remove();
+                    Doc.AddDocToList(CurrentUserUtils.MyRecentlyClosed, "data", tab.DashDoc, undefined, true, true);
+                };
+                const docIcon = <FontAwesomeIcon onPointerDown={dragBtnDown} icon={iconType} />;
+                const closeIcon = <FontAwesomeIcon icon={"times"} />;
+                ReactDOM.render(docIcon, iconWrap);
+                ReactDOM.render(closeIcon, closeWrap);
+                // tab.element[0].append(closeWrap);
+                tab.element[0].prepend(iconWrap);
+                tab._disposers.layerDisposer = reaction(() => ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
+                    ({ layer, color }) => {
+                        const textColor = lightOrDark(this.tabColor); //not working with StyleProp.Color
+                        titleEle.style.color = textColor;
+                        titleEle.style.backgroundColor = "transparent";
+                        iconWrap.style.color = textColor;
+                        closeWrap.style.color = textColor;
+                        moreInfoDrag.style.backgroundColor = textColor;
+                        tab.element[0].style.background = !layer ? color : "dimgrey";
+                    }, { fireImmediately: true });
+                // TODO:glr fix
+                // tab.element[0].style.borderTopRightRadius = "8px";
+                // tab.element[0].children[1].appendChild(toggle);
+                // tab._disposers.layerDisposer = reaction(() =>
+                //     ({ layer: tab.DashDoc.activeLayer, color: this.tabColor }),
+                //     ({ layer, color }) => toggle.style.background = !layer ? color : "dimgrey", { fireImmediately: true });
             }
             // shifts the focus to this tab when another tab is dragged over it
             tab.element[0].onmouseenter = (e: MouseEvent) => {
@@ -103,13 +146,11 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     tab.setActive(true);
                 }
             };
-            const dragBtnDown = (e: React.PointerEvent) => {
-                setupMoveUpEvents(this, e, e => !e.defaultPrevented && DragManager.StartDocumentDrag([dragHdl], new DragManager.DocumentDragData([doc], doc.dropAction as dropActionType), e.clientX, e.clientY), returnFalse, emptyFunction);
-            };
+
 
             // select the tab document when the tab is directly clicked and activate the tab whenver the tab document is selected
             titleEle.onpointerdown = action((e: any) => {
-                if (e.target.className !== "lm_close_tab") {
+                if (e.target.className !== "lm_iconWrap") {
                     if (this.view) SelectionManager.SelectView(this.view, false);
                     else this._activated = true;
                     if (Date.now() - titleEle.lastClick < 1000) titleEle.select();
@@ -123,25 +164,25 @@ export class TabDocView extends React.Component<TabDocViewProps> {
                     const toggle = tab.element[0].children[1].children[0] as HTMLInputElement;
                     selected && tab.contentItem !== tab.header.parent.getActiveContentItem() &&
                         UndoManager.RunInBatch(() => tab.header.parent.setActiveContentItem(tab.contentItem), "tab switch");
-                    toggle.style.fontWeight = selected ? "bold" : "";
-                    toggle.style.textTransform = selected ? "uppercase" : "";
+                    // toggle.style.fontWeight = selected ? "bold" : "";
+                    // toggle.style.textTransform = selected ? "uppercase" : "";
                 }));
 
             //attach the selection doc buttons menu to the drag handle
             const stack = tab.contentItem.parent;
-            const dragHdl = document.createElement("div");
-            dragHdl.className = "lm_drag_tab";
+            const moreInfoDrag = document.createElement("div");
+            moreInfoDrag.className = "lm_iconWrap";
             tab._disposers.buttonDisposer = reaction(() => this.view, view =>
-                view && [ReactDOM.render(<span className="tabDocView-drag" onPointerDown={dragBtnDown}><CollectionDockingViewMenu views={() => [view]} Stack={stack} /></span>, dragHdl), tab._disposers.buttonDisposer?.()],
+                view && [ReactDOM.render(<span><CollectionDockingViewMenu views={() => [view]} Stack={stack} /></span>, moreInfoDrag), tab._disposers.buttonDisposer?.()],
                 { fireImmediately: true });
-            tab.reactComponents = [dragHdl];
-            tab.closeElement.before(dragHdl);
+            // tab.reactComponents = [moreInfoDrag];
+            // tab.element[0].children[3].before(moreInfoDrag);
 
             // highlight the tab when the tab document is brushed in any part of the UI
             tab._disposers.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => {
                 titleEle.value = title;
-                titleEle.style.padding = degree ? 0 : 2;
-                titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
+                // titleEle.style.padding = degree ? 0 : 2;
+                // titleEle.style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
             }, { fireImmediately: true });
 
             // clean up the tab when it is closed
@@ -221,9 +262,9 @@ export class TabDocView extends React.Component<TabDocViewProps> {
         })).observe(this.props.glContainer._element[0]);
         this.props.glContainer.layoutManager.on("activeContentItemChanged", this.onActiveContentItemChanged);
         this.props.glContainer.tab?.isActive && this.onActiveContentItemChanged(undefined);
-        this._tabReaction = reaction(() => ({ selected: this.active(), title: this.tab?.titleElement[0] }),
-            ({ selected, title }) => title && (title.style.backgroundColor = selected ? "white" : ""),
-            { fireImmediately: true });
+        // this._tabReaction = reaction(() => ({ selected: this.active(), title: this.tab?.titleElement[0] }),
+        //     ({ selected, title }) => title && (title.style.backgroundColor = selected ? "white" : ""),
+        //     { fireImmediately: true });
     }
 
     componentWillUnmount() {
@@ -243,10 +284,10 @@ export class TabDocView extends React.Component<TabDocViewProps> {
     }
 
     // adds a tab to the layout based on the locaiton parameter which can be:
-    //  close[:{left,right,top,bottom}]  - e.g., "close" will close the tab, "close:left" will close the left tab, 
+    //  close[:{left,right,top,bottom}]  - e.g., "close" will close the tab, "close:left" will close the left tab,
     //  add[:{left,right,top,bottom}] - e.g., "add" will add a tab to the current stack, "add:right" will add a tab on the right
-    //  replace[:{left,right,top,bottom,<any string>}] - e.g., "replace" will replace the current stack contents, 
-    //                                  "replace:right" - will replace the stack on the right named "right" if it exists, or create a stack on the right with that name, 
+    //  replace[:{left,right,top,bottom,<any string>}] - e.g., "replace" will replace the current stack contents,
+    //                                  "replace:right" - will replace the stack on the right named "right" if it exists, or create a stack on the right with that name,
     //                                   "replace:monkeys" - will replace any tab that has the label 'monkeys', or a tab with that label will be created by default on the right
     //  inPlace - will add the document to any collection along the path from the document to the docking view that has a field isInPlaceContainer. if none is found, inPlace adds a tab to current stack
     addDocTab = (doc: Doc, location: string) => {
@@ -460,4 +501,4 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
                 </div>
             </div>;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index ead5e166e..a8d4235bd 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -21,8 +21,6 @@ $large-padding: 32px;
 //icon sizes
 $icon-size: 28px;
 
-$antimodemenu-height: 36px;
-
 // fonts
 $sans-serif: "Noto Sans", sans-serif;
 $large-header: 16px;
@@ -33,6 +31,8 @@ $small-text: 9px;
 // misc values
 $border-radius: 0.3em;
 $search-thumnail-size: 130;
+$topbar-height: 32px;
+$antimodemenu-height: 36px;
 
 // dragged items
 $contextMenu-zindex: 100000; // context menu shows up over everything
diff --git a/src/client/views/global/globalEnums.tsx b/src/client/views/global/globalEnums.tsx
index 1e0381c33..2aeb8e338 100644
--- a/src/client/views/global/globalEnums.tsx
+++ b/src/client/views/global/globalEnums.tsx
@@ -31,4 +31,8 @@ export enum Padding {
 
 export enum IconSizes {
     ICON_SIZE = "28px",
+}
+
+export enum Borders {
+    STANDARD = "solid 1px #9F9F9F"
 }
\ No newline at end of file
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
new file mode 100644
index 000000000..324b96dbd
--- /dev/null
+++ b/src/client/views/topbar/TopBar.scss
@@ -0,0 +1,211 @@
+@import "../global/globalCssVariables";
+
+.topbar-container {
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    position: relative;
+    font-size: 10px;
+    line-height: 1;
+    overflow-y: auto;
+    overflow-x: visible;
+    background: $dark-gray;
+    overflow: visible;
+    z-index: 1000;
+
+    .topbar-bar {
+        height: $topbar-height;
+        display: grid;
+        grid-auto-columns: 33.3% 33.3% 33.3%;
+        align-items: center;
+        background-color: $dark-gray;
+
+        .topbar-center {
+            grid-column: 2;
+            display: inline-flex;
+            justify-content: center;
+            align-items: center;
+
+            .topbar-lozenge-dashboard {
+                display: flex;
+
+                .topbar-dashboards {
+                    display: none;
+                }
+
+                .topbar-dashSelect {
+                    border: none;
+                    background-color: transparent;
+                    color: black;
+                    font-family: 'Roboto';
+                    font-size: 17;
+                    font-weight: 500;
+
+                    &:hover {
+                        cursor: pointer;
+                    }
+                }
+            }
+
+            .topbar-lozenge-dashboard:hover {
+                .topbar-dashboards {
+                    display: inline-flex;
+                }
+            }
+        }
+
+        .topBar-icon {
+            color: black;
+            cursor: pointer;
+            font-size: 15px;
+            height: 30;
+            width: 30;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-right: 5px;
+            justify-self: center;
+            align-self: center;
+            border-radius: 100%;
+            transition: linear 0.1s;
+            background-color: #92adb900;
+        }
+
+        .topBar-icon:hover {
+            background-color: rgba(0, 0, 0, 0.15);
+        }
+
+        .topbar-right {
+            grid-column: 3;
+            position: relative;
+            display: flex;
+            justify-content: flex-end;
+
+            .topbar-lozenge-user,
+            .topbar-lozenge {
+                height: 23;
+                font-size: 12;
+                color: black;
+                font-family: 'Roboto';
+                font-weight: 400;
+                padding: 4px;
+                align-self: center;
+                margin-right: 7px;
+                display: flex;
+                align-items: center;
+                border: black 1px solid;
+
+                .topbar-logoff {
+                    border-radius: 3px;
+                    background: olivedrab;
+                    color: white;
+                    display: none;
+                    margin-left: 5px;
+                    padding: 1px 2px 1px 2px;
+                    cursor: pointer;
+                }
+
+                .topbar-logoff {
+                    background: red;
+                }
+
+                .topbar-dashSelect {
+                    border: none;
+                    background-color: transparent;
+                    color: black;
+                    font-family: 'Roboto';
+                    font-size: 17;
+                    font-weight: 500;
+
+                    &:hover {
+                        cursor: pointer;
+                    }
+                }
+            }
+
+            .topbar-lozenge-user:hover {
+                .topbar-logoff {
+                    display: inline-block;
+                }
+            }
+
+        }
+
+        .topbar-left {
+            grid-column: 1;
+            color: black;
+            font-family: 'Roboto';
+            position: relative;
+            display: flex;
+            width: 450;
+        }
+
+        .topbar-barChild {
+
+            &.topbar-collection {
+                flex: 0 1 auto;
+                margin-left: 2px;
+                margin-right: 2px
+            }
+
+            &.topbar-input {
+                margin:5px;
+                border-radius:20px;
+                border:$dark-gray;    
+                display: block;
+                width: 130px;
+                -webkit-transition: width 0.4s;
+                transition: width 0.4s;
+                /* align-self: stretch; */
+                outline: none;
+
+                &:focus {
+                    width: 500px;
+                    outline: none;
+                }
+            }
+
+            &.topbar-filter {
+                align-self: stretch;
+
+                button {
+                    transform: none;
+
+                    &:hover {
+                        transform: none;
+                    }
+                }
+            }
+
+            &.topbar-submit {
+                margin-left: 2px;
+                margin-right: 2px
+            }
+
+            &.topbar-close {
+                color: $white;
+                max-height: $topbar-height;
+            }
+        }
+    }
+}
+
+.topbar-results {
+    display: flex;
+    flex-direction: column;
+    top: 300px;
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+    overflow: visible;
+
+    .no-result {
+        width: 500px;
+        background: $light-gray;
+        padding: 10px;
+        height: 50px;
+        text-transform: uppercase;
+        text-align: left;
+        font-weight: bold;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
new file mode 100644
index 000000000..79239d4ea
--- /dev/null
+++ b/src/client/views/topbar/TopBar.tsx
@@ -0,0 +1,58 @@
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import * as React from 'react';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { StrCast } from '../../../fields/Types';
+import { Utils } from '../../../Utils';
+import { CurrentUserUtils } from "../../util/CurrentUserUtils";
+import { ColorScheme, SettingsManager } from "../../util/SettingsManager";
+import { undoBatch } from "../../util/UndoManager";
+import "./TopBar.scss";
+import { Colors, Borders } from "../global/globalEnums";
+
+export const TopBar = () => {
+
+    const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
+    return (
+        <div style={{ pointerEvents: "all" }} className="topbar-container">
+            <div className="topbar-bar" style={{ background: Doc.UserDoc().colorScheme === ColorScheme.Dark ? Colors.DARK_GRAY : Colors.LIGHT_GRAY, borderBottom: Borders.STANDARD }}>
+                <div className="topbar-center" >
+                    <div className="topbar-lozenge-dashboard">
+                        <select className="topbar-dashSelect" onChange={e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)])}
+                            value={myDashboards.indexOf(CurrentUserUtils.ActiveDashboard)}
+                            style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
+                            {myDashboards.map((dash, i) => <option key={dash[Id]} value={i}> {StrCast(dash.title)} </option>)}
+                        </select>
+                        <div className="topbar-dashboards">
+                            <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}
+                                style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
+                                <FontAwesomeIcon icon="plus"></FontAwesomeIcon>
+                            </div>
+                            <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.snapshotDashboard(Doc.UserDoc()))}
+                                style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
+                                <FontAwesomeIcon icon="camera"></FontAwesomeIcon>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div className="topbar-right" >
+                    <div className="topbar-icon"
+                        style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
+                        <FontAwesomeIcon icon="question-circle"></FontAwesomeIcon>
+                    </div>
+                    <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}
+                        style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
+                        <FontAwesomeIcon icon="cog"></FontAwesomeIcon>
+                    </div>
+                    <div className="topbar-lozenge-user">
+                        {`${Doc.CurrentUserEmail}`}
+                        <div className="topbar-logoff" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
+                            Logoff
+                        </div>
+                    </div>
+                </div>
+
+            </div >
+        </div >
+    );
+}
\ No newline at end of file
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 464a8ad05..ee8d36f09 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -23,6 +23,7 @@ import { Cast, FieldValue, NumCast, StrCast, ToConstructor } from "./Types";
 import { AudioField, ImageField, PdfField, VideoField, WebField } from "./URLField";
 import { deleteProperty, GetEffectiveAcl, getField, getter, makeEditable, makeReadOnly, normalizeEmail, setter, SharingPermissions, updateFunction } from "./util";
 import JSZip = require("jszip");
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
 
 export namespace Field {
     export function toKeyValueString(doc: Doc, key: string): string {
@@ -1184,7 +1185,10 @@ export namespace Doc {
             case DocumentType.IMG: return "image";
             case DocumentType.COMPARISON: return "columns";
             case DocumentType.RTF: return "sticky-note";
-            case DocumentType.COL: return !doc?.isFolder ? "folder" + (isOpen ? "-open" : "") : "chevron-" + (isOpen ? "down" : "right");
+            case DocumentType.COL:
+                const folder: IconProp = isOpen ? "folder-open" : "folder";
+                const chevron: IconProp = isOpen ? "chevron-down" : "chevron-right"
+                return !doc?.isFolder ? folder : chevron;
             case DocumentType.WEB: return "globe-asia";
             case DocumentType.SCREENSHOT: return "photo-video";
             case DocumentType.WEBCAM: return "video";
-- 
cgit v1.2.3-70-g09d2


From c9f379adab864132e6cf044f808a43254601e4bb Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Fri, 30 Jul 2021 13:26:25 -0400
Subject: major UI / updates + refactoring

---
 deploy/assets/favicon.png                          |  Bin 0 -> 22180 bytes
 deploy/index.html                                  |  114 +-
 deploy/loader.css                                  |   85 +
 deploy/loader.js                                   |   14 +
 src/client/documents/Documents.ts                  |    4 +-
 src/client/util/CurrentUserUtils.ts                |   44 +-
 src/client/views/AntimodeMenu.scss                 |    1 +
 src/client/views/DocumentButtonBar.tsx             |    2 +-
 src/client/views/MainView.scss                     |   30 +-
 src/client/views/MainView.tsx                      |   29 +-
 src/client/views/PropertiesView.tsx                |    2 +-
 src/client/views/_nodeModuleOverrides.scss         |    4 +-
 src/client/views/collections/CollectionMenu.scss   |    4 +-
 src/client/views/collections/CollectionMenu.tsx    |    2 +-
 src/client/views/collections/TabDocView.tsx        |    2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   10 +-
 .../collections/collectionFreeForm/MarqueeView.tsx |    3 +-
 src/client/views/global/globalCssVariables.scss    |    3 +
 src/client/views/nodes/DocumentContentsView.tsx    |    4 +-
 src/client/views/nodes/DocumentView.tsx            |    2 +-
 src/client/views/nodes/FontIconBox.tsx             |    3 +-
 src/client/views/nodes/PresBox.scss                | 1243 ----------
 src/client/views/nodes/PresBox.tsx                 | 2472 --------------------
 .../views/nodes/formattedText/RichTextMenu.tsx     |   10 +-
 src/client/views/nodes/trails/PresBox.scss         | 1243 ++++++++++
 src/client/views/nodes/trails/PresBox.tsx          | 2440 +++++++++++++++++++
 src/client/views/nodes/trails/PresElementBox.scss  |  235 ++
 src/client/views/nodes/trails/PresElementBox.tsx   |  388 +++
 src/client/views/nodes/trails/PresEnums.ts         |   28 +
 src/client/views/nodes/trails/index.ts             |    3 +
 .../views/presentationview/PresElementBox.scss     |  235 --
 .../views/presentationview/PresElementBox.tsx      |  386 ---
 src/client/views/topbar/TopBar.scss                |   12 +-
 src/client/views/topbar/TopBar.tsx                 |   89 +-
 tslint.json                                        |   41 +-
 35 files changed, 4587 insertions(+), 4600 deletions(-)
 create mode 100644 deploy/assets/favicon.png
 create mode 100644 deploy/loader.css
 create mode 100644 deploy/loader.js
 delete mode 100644 src/client/views/nodes/PresBox.scss
 delete mode 100644 src/client/views/nodes/PresBox.tsx
 create mode 100644 src/client/views/nodes/trails/PresBox.scss
 create mode 100644 src/client/views/nodes/trails/PresBox.tsx
 create mode 100644 src/client/views/nodes/trails/PresElementBox.scss
 create mode 100644 src/client/views/nodes/trails/PresElementBox.tsx
 create mode 100644 src/client/views/nodes/trails/PresEnums.ts
 create mode 100644 src/client/views/nodes/trails/index.ts
 delete mode 100644 src/client/views/presentationview/PresElementBox.scss
 delete mode 100644 src/client/views/presentationview/PresElementBox.tsx

(limited to 'src/client/views/MainView.tsx')

diff --git a/deploy/assets/favicon.png b/deploy/assets/favicon.png
new file mode 100644
index 000000000..59595b910
Binary files /dev/null and b/deploy/assets/favicon.png differ
diff --git a/deploy/index.html b/deploy/index.html
index dda0c6457..d96215391 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -1,114 +1,22 @@
 <html style="overflow: hidden;">
 
 <head>
-    <title>Dash Web</title>
-    <link href="https://fonts.googleapis.com/css?family=Fjalla+One|Hind+Siliguri:300" rel="stylesheet">
-    <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500' rel='stylesheet'>
+    <title>Dash</title>
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link
+        href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"
+        rel="stylesheet">
+    <link rel="shortcut icon" type="image/jpg" href="./assets/favicon.png" />
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
         integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
     <script src="https://cdnjs.cloudflare.com/ajax/libs/typescript/3.3.1/typescript.min.js"></script>
-
-    <script>
-        function getCookie(cname) {
-            var name = cname + "=";
-            var ca = document.cookie.split(';');
-            for (var i = 0; i < ca.length; i++) {
-                var c = ca[i];
-                while (c.charAt(0) == ' ') {
-                    c = c.substring(1);
-                }
-                if (c.indexOf(name) == 0) {
-                    return Number(c.substring(name.length, c.length));
-                }
-            }
-            return 3000;
-        } 
-    </script>
-    <style>
-        .dash-loader {
-            display: flex;
-            align-content: center;
-            justify-content: center;
-            background-color: #AEDDF8;
-            transition: 3s;
-            z-index: 10;
-            width: 100vw;
-            height: 100vh;
-        }
-
-        .dash-loader-container {
-            display: grid;
-            grid-auto-rows: auto 30px auto;
-        }
-
-        .dash-progress-bar {
-            width: 200px;
-            height: 5px;
-            align-self: center;
-            margin-top: 20px;
-            background-color: #ececec;
-            border-radius: 5px;
-            overflow: hidden;
-        }
-
-        .dash-progress {
-            width: 0%;
-            height: 20px;
-            background-color: #5b9fdd;
-            transition: 0.1s;
-        }
-
-        .dash-animation-container {
-            width: 10vw;
-            height: 10vw;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            border-radius: 100%;
-            background-color: #5B9FDD;
-            justify-self: center;
-            align-self: flex-end;
-        }
-
-        .dash-loader-text {
-            font-size: 15px;
-            font-family: "Roboto";
-            text-align: center;
-            color: #5B9FDD;
-        }
-
-        .dash-d-path {
-            stroke-dasharray: 1000;
-            stroke-dashoffset: 1000;
-            animation: dash-d-path 3s linear infinite;
-        }
-
-        @keyframes dash-d-path {
-            0% {
-                stroke-dashoffset: 1000;
-            }
-
-            20% {
-                stroke-dashoffset: 0;
-            }
-
-            70% {
-                stroke-dashoffset: 0;
-            }
-
-            90% {
-                stroke-dashoffset: 1000;
-            }
-
-            100% {
-                stroke-dashoffset: 1000;
-            }
-        }
-    </style>
+    <script src="loader.js"></script>
+    <link rel="stylesheet" href="./loader.css" />
 </head>
 
 <body style="display:flex" id="dash-body">
-    <div class="dash-loader" id="loader" style="z-index:10; width:100%; height:100%;">
+    <div class="dash-loader" id="loader">
         <div class="dash-loader-container">
             <div class="dash-animation-container">
                 <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100px"
@@ -127,7 +35,7 @@
                     console.log("Last Load = " + load);
                     let dashmesg = (width, msg) => {
                         if (document.getElementById("dash-progress")) document.getElementById("dash-progress").style.width = width
-                        if (document.getElementById("dash-progress")) document.getElementById("dash-progress").innerHTML = msg
+                        if (document.getElementById("dash-progress")) document.getElementById("dash-loader-text").innerHTML = msg
                     }
                     setTimeout(() => dashmesg("10%", "Loading Dash..."), load / 10);
                     setTimeout(() => dashmesg("33%", "Preparing dashboards..."), load / 3);
diff --git a/deploy/loader.css b/deploy/loader.css
new file mode 100644
index 000000000..4be0cc98c
--- /dev/null
+++ b/deploy/loader.css
@@ -0,0 +1,85 @@
+.dash-loader {
+    display: flex;
+    align-content: center;
+    justify-content: center;
+    background-color: #BDDDF5;
+    transition: 3s;
+    z-index: 10;
+    z-index:10; 
+    width:100%;
+    height:100%;
+}
+
+.dash-loader-container {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    align-content: center;
+}
+
+.dash-progress-bar {
+    width: 200px;
+    height: 5px;
+    align-self: center;
+    margin-top: 20px;
+    background-color: #ececec;
+    border-radius: 5px;
+    overflow: hidden;
+}
+
+.dash-progress {
+    width: 0%;
+    height: 20px;
+    background-color: #4476F7;
+    transition: 0.1s;
+}
+
+.dash-animation-container {
+    width: 10vw;
+    height: 10vw;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 100%;
+    background-color: #4476F7;
+    justify-self: center;
+}
+
+.dash-loader-text {
+    font-size: 15px;
+    font-family: "Roboto";
+    font-weight: bold;
+    text-align: center;
+    color: #4476F7;
+    user-select: none;
+    -webkit-user-select: none;
+}
+
+.dash-d-path {
+    stroke-dasharray: 1000;
+    stroke-dashoffset: 1000;
+    animation: dash-d-path 3s linear infinite;
+}
+
+@keyframes dash-d-path {
+    0% {
+        stroke-dashoffset: 1000;
+    }
+
+    20% {
+        stroke-dashoffset: 0;
+    }
+
+    70% {
+        stroke-dashoffset: 0;
+    }
+
+    90% {
+        stroke-dashoffset: 1000;
+    }
+
+    100% {
+        stroke-dashoffset: 1000;
+    }
+}
\ No newline at end of file
diff --git a/deploy/loader.js b/deploy/loader.js
new file mode 100644
index 000000000..0be421e14
--- /dev/null
+++ b/deploy/loader.js
@@ -0,0 +1,14 @@
+function getCookie(cname) {
+    var name = cname + "=";
+    var ca = document.cookie.split(';');
+    for (var i = 0; i < ca.length; i++) {
+        var c = ca[i];
+        while (c.charAt(0) == ' ') {
+            c = c.substring(1);
+        }
+        if (c.indexOf(name) == 0) {
+            return Number(c.substring(name.length, c.length));
+        }
+    }
+    return 3000;
+} 
\ No newline at end of file
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f1db3e32c..81465a241 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -45,14 +45,14 @@ import { LabelBox } from "../views/nodes/LabelBox";
 import { LinkBox } from "../views/nodes/LinkBox";
 import { LinkDescriptionPopup } from "../views/nodes/LinkDescriptionPopup";
 import { PDFBox } from "../views/nodes/PDFBox";
-import { PresBox } from "../views/nodes/PresBox";
+import { PresBox } from "../views/nodes/trails/PresBox";
 import { ScreenshotBox } from "../views/nodes/ScreenshotBox";
 import { ScriptingBox } from "../views/nodes/ScriptingBox";
 import { SliderBox } from "../views/nodes/SliderBox";
 import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox";
 import { VideoBox } from "../views/nodes/VideoBox";
 import { WebBox } from "../views/nodes/WebBox";
-import { PresElementBox } from "../views/presentationview/PresElementBox";
+import { PresElementBox } from "../views/nodes/trails/PresElementBox";
 import { SearchBox } from "../views/search/SearchBox";
 import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo";
 import { DocumentType } from "./DocumentTypes";
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 22504f102..62fab1b23 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -35,6 +35,8 @@ import { UndoManager } from "./UndoManager";
 import { SnappingManager } from "./SnappingManager";
 import { InkTool } from "../../fields/InkField";
 import { computedFn } from "mobx-utils";
+import { ColorScheme } from "./SettingsManager";
+import { Colors } from "../views/global/globalEnums";
 
 
 export let resolvedPorts: { server: number, socket: number };
@@ -472,7 +474,7 @@ export class CurrentUserUtils {
             { toolTip: "Tap to create a videoWall", title: "Wall", icon: "photo-video", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyWall as Doc },
             { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true },
             { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc },
-            { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true },
+            // { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true },
             { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc },
             { toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc },
             { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc },
@@ -534,8 +536,8 @@ export class CurrentUserUtils {
             { title: "Sharing", target: Cast(doc.mySharedDocs, Doc, null), icon: "users", click: 'selectMainMenu(self)', watchedDocuments: doc.mySharedDocs as Doc },
             // { title: "Filter", target: Cast(doc.currentFilter, Doc, null), icon: "filter", click: 'selectMainMenu(self)' },
             { title: "Pres. Trails", target: Cast(doc.myPresentations, Doc, null), icon: "pres-trail", click: 'selectMainMenu(self)' },
-            { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' },
-            { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' },
+            // { title: "Help", target: undefined as any, icon: "question-circle", click: 'selectMainMenu(self)' },
+            // { title: "Settings", target: undefined as any, icon: "cog", click: 'selectMainMenu(self)' },
             { title: "User Doc", target: Cast(doc.myUserDoc, Doc, null), icon: "address-card", click: 'selectMainMenu(self)' },
         ];
     }
@@ -561,7 +563,6 @@ export class CurrentUserUtils {
                     dontUndo: true,
                     title,
                     target,
-                    backgroundColor: "black",
                     _dropAction: "alias",
                     _removeDropProperties: new List<string>(["dropAction", "_stayInCollection"]),
                     _width: 60,
@@ -576,8 +577,10 @@ export class CurrentUserUtils {
                 title: "menuItemPanel",
                 childDropAction: "alias",
                 _chromeHidden: true,
+                backgroundColor: Colors.DARK_GRAY,
+                boxShadow: "rgba(0,0,0,0)",
                 dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }),
-                backgroundColor: "black", ignoreClick: true,
+                ignoreClick: true,
                 _gridGap: 0,
                 _yMargin: 0,
                 _yPadding: 0, _xMargin: 0, _autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, system: true
@@ -587,8 +590,6 @@ export class CurrentUserUtils {
         PromiseValue(Cast(doc.menuStack, Doc)).then(stack => {
             stack && PromiseValue(stack.data).then(btns => {
                 DocListCastAsync(btns).then(bts => bts?.forEach(btn => {
-                    btn.color = "white";
-                    btn._backgroundColor = "";
                     btn.dontUndo = true;
                     btn.system = true;
                     if (btn.title === "Catalog" || btn.title === "My Files") { // migration from Catalog to My Files
@@ -759,7 +760,7 @@ export class CurrentUserUtils {
         await doc.myDashboards;
         if (doc.myDashboards === undefined) {
             doc.myDashboards = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "My Dashboards", _height: 400, childHideLinkButton: true,
+                title: "My Dashboards", _showTitle: "title", _height: 400, childHideLinkButton: true,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
@@ -775,7 +776,7 @@ export class CurrentUserUtils {
         await doc.myPresentations;
         if (doc.myPresentations === undefined) {
             doc.myPresentations = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "My Presentations", _height: 100,
+                title: "My Trails", _showTitle: "title", _height: 100,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
@@ -794,7 +795,7 @@ export class CurrentUserUtils {
             doc.myFileOrphans = Docs.Create.TreeDocument([], { title: "Unfiled", _stayInCollection: true, system: true, isFolder: true });
             doc.myFileRoot = Docs.Create.TreeDocument([], { title: "file root", _stayInCollection: true, system: true, isFolder: true });
             doc.myFilesystem = new PrefetchProxy(Docs.Create.TreeDocument([doc.myFileRoot as Doc, doc.myFileOrphans as Doc], {
-                title: "My Documents", _height: 100,
+                title: "My Documents", _showTitle: "title", _height: 100,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 isFolder: true, treeViewType: "fileSystem", childHideLinkButton: true,
@@ -808,7 +809,7 @@ export class CurrentUserUtils {
         // setup Recently Closed library item
         if (doc.myRecentlyClosedDocs === undefined) {
             doc.myRecentlyClosedDocs = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "Recently Closed", treeViewShowClearButton: true, childHideLinkButton: true,
+                title: "Recently Closed", _showTitle: "title", treeViewShowClearButton: true, childHideLinkButton: true,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
@@ -839,7 +840,7 @@ export class CurrentUserUtils {
             doc.treeViewOpen = true;
             doc.treeViewExpandedView = "fields";
             doc.myUserDoc = new PrefetchProxy(Docs.Create.TreeDocument([doc], {
-                treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc",
+                treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, title: "My UserDoc", _showTitle: "title",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
             })) as any as Doc;
@@ -859,6 +860,7 @@ export class CurrentUserUtils {
     static async setupSidebarButtons(doc: Doc) {
         CurrentUserUtils.setupSidebarContainer(doc);
         await CurrentUserUtils.setupToolsBtnPanel(doc);
+        CurrentUserUtils.setupImportSidebar(doc);
         CurrentUserUtils.setupDashboards(doc);
         CurrentUserUtils.setupPresentations(doc);
         CurrentUserUtils.setupFilesystem(doc);
@@ -891,6 +893,7 @@ export class CurrentUserUtils {
         (doc["dockedBtn-undo"] as Doc).dontUndo = true;
         (doc["dockedBtn-redo"] as Doc).dontUndo = true;
     }
+
     // sets up the default set of documents to be shown in the Overlay layer
     static setupOverlays(doc: Doc) {
         if (doc.myOverlayDocs === undefined) {
@@ -924,7 +927,8 @@ export class CurrentUserUtils {
             if (!sharedDocs) {
                 sharedDocs = Docs.Create.StackingDocument([], {
                     title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "none", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
-                    _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add, _chromeHidden: true,
+                    _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add,
+                    _chromeHidden: true, boxShadow: "0 0",
                 }, sharingDocumentId + "outer", sharingDocumentId);
                 (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Add;
             }
@@ -939,14 +943,14 @@ export class CurrentUserUtils {
     static setupImportSidebar(doc: Doc) {
         if (doc.myImportDocs === undefined) {
             doc.myImportDocs = new PrefetchProxy(Docs.Create.StackingDocument([], {
-                title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _showTitle: "title", _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
+                title: "My ImportDocuments", _forceActive: true, ignoreClick: true, _stayInCollection: true, _hideContextMenu: true, childLimitHeight: 0,
                 childDropAction: "alias", _autoHeight: true, _yMargin: 50, _gridGap: 15, _lockedPosition: true, system: true, _chromeHidden: true,
             }));
         }
         if (doc.myImportPanel === undefined) {
             const uploads = Cast(doc.myImportDocs, Doc, null);
             const newUpload = CurrentUserUtils.ficon({ onClick: ScriptField.MakeScript("importDocument()"), toolTip: "Import External document", _stayInCollection: true, _hideContextMenu: true, title: "Import", icon: "upload", system: true });
-            doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true }));
+            doc.myImportPanel = new PrefetchProxy(Docs.Create.StackingDocument([newUpload, uploads], { title: "My ImportPanel", _yMargin: 20, _showTitle: "title", ignoreClick: true, _chromeHidden: true, _stayInCollection: true, _hideContextMenu: true, _lockedPosition: true, system: true, boxShadow: "0 0" }));
         }
     }
 
@@ -1007,10 +1011,14 @@ export class CurrentUserUtils {
                 const mygroups = groups?.filter(group => JSON.parse(StrCast(group.members)).includes(Doc.CurrentUserEmail)) || [];
                 SnappingManager.SetCachedGroups(["Public", ...mygroups?.map(g => StrCast(g.title))]);
             }, { fireImmediately: true });
+        // Document properties on load
         doc.system = true;
+        doc.darkScheme = ColorScheme.Dark;
         doc.noviceMode = doc.noviceMode === undefined ? "true" : doc.noviceMode;
         doc.title = Doc.CurrentUserEmail;
         doc._raiseWhenDragged = true;
+        doc._showLabel = false;
+        doc._showMenuLabel = true;
         doc.activeInkColor = StrCast(doc.activeInkColor, "rgb(0, 0, 0)");
         doc.activeInkWidth = StrCast(doc.activeInkWidth, "1");
         doc.activeInkBezier = StrCast(doc.activeInkBezier, "0");
@@ -1201,7 +1209,7 @@ export class CurrentUserUtils {
         const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row");
         Doc.AddDocToList(myPresentations, "data", presentation);
         userDoc.activePresentation = presentation;
-        const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
+        const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`);
         const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
         const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
         const createDashboard = ScriptField.MakeScript(`createNewDashboard()`);
@@ -1257,6 +1265,4 @@ Scripting.addGlobal(function createNewPresentation() { return MainView.Instance.
 Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); },
     "returns all the links to the document or its annotations", "(doc: any)");
 Scripting.addGlobal(function importDocument() { return CurrentUserUtils.importDocument(); },
-    "imports files from device directly into the import sidebar");
-Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; },
-    "toggle between regular rendeing and an informal sketch/comic style");
+    "imports files from device directly into the import sidebar");
\ No newline at end of file
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index b509f9f54..e23bf27c1 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -6,6 +6,7 @@
     z-index: 10001;
     height: $antimodemenu-height;
     background: $dark-gray;
+    border-bottom: $standard-border;
     // box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
     // border-radius: 0px 6px 6px 6px;
     z-index: 1001;
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index a5d80cd22..b11aa99b0 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -24,7 +24,7 @@ import { DocumentView } from './nodes/DocumentView';
 import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
 import { TemplateMenu } from "./TemplateMenu";
 import React = require("react");
-import { PresBox } from './nodes/PresBox';
+import { PresBox } from './nodes/trails/PresBox';
 import { undoBatch } from '../util/UndoManager';
 import { CollectionViewType } from './collections/CollectionView';
 const higflyout = require("@hig/flyout");
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 2069986ad..ba1c91720 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -22,10 +22,6 @@
     height: 100%;
 }
 
-.mainContent-div-flyout {
-    left: calc(-1 * var(--flyoutHandleWidth));
-}
-
 // add nodes menu. Note that the + button is actually an input label, not an actual button.
 .mainView-docButtons {
     position: absolute;
@@ -111,14 +107,21 @@
     user-select: none;
 }
 
+.properties-container {
+    height: 100%;
+    position: relative;
+    left: 100%;
+    top: calc(-100% - 36px);
+    z-index: 3000;
+}
+
 .mainView-propertiesDragger {
     //background-color: rgb(140, 139, 139);
-    background-color: $light-gray;
+    background-color: $medium-gray;
     height: 55px;
     width: 17px;
     position: absolute;
     top: 50%;
-    border: 1px black solid;
     border-radius: 0;
     border-top-left-radius: 10px;
     border-bottom-left-radius: 10px;
@@ -141,18 +144,6 @@
     }
 }
 
-.mainiView-propertiesView {
-    display: flex;
-    flex-direction: column;
-    height: 100%;
-    position: absolute;
-    right: 0;
-    top: 0;
-    border-left: solid 1px;
-    z-index: 100000;
-    cursor: auto;
-}
-
 .mainView-innerContent, .mainView-innerContent-dark {
     display: contents;
     flex-direction: row;
@@ -171,7 +162,7 @@
     }
 
     .propertiesView {
-        right: 0;
+        left: 0;
         position: absolute;
         z-index: 2;
         background-color: $medium-gray;
@@ -220,6 +211,7 @@
 .mainView-menuPanel {
     min-width: var(--menuPanelWidth);
     background-color: $dark-gray;
+    border-right: $standard-border;
 
     .collectionStackingView {
         scrollbar-width: none;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 7d6bfbd40..49f4f7a6e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -64,6 +64,7 @@ import { PropertiesView } from './PropertiesView';
 import { SearchBox } from './search/SearchBox';
 import { DefaultStyleProvider, DashboardStyleProvider, StyleProp } from './StyleProvider';
 import { TopBar } from './topbar/TopBar';
+import { Colors } from './global/globalEnums';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -179,12 +180,12 @@ export class MainView extends React.Component {
         const targets = document.elementsFromPoint(e.x, e.y);
         if (targets.length) {
             const targClass = targets[0].className.toString();
-            if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
-                const check = targets.some((thing) =>
-                    (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                        thing.className === "collectionSchema-header-menuOptions"));
-                !check && SearchBox.Instance.resetSearch(true);
-            }
+            // if (SearchBox.Instance._searchbarOpen || SearchBox.Instance.open) {
+            //     const check = targets.some((thing) =>
+            //         (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
+            //             thing.className === "collectionSchema-header-menuOptions"));
+            //     !check && SearchBox.Instance.resetSearch(true);
+            // }
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
             !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
         }
@@ -193,7 +194,7 @@ export class MainView extends React.Component {
     initEventListeners = () => {
         window.addEventListener("drop", e => e.preventDefault(), false);  // prevent default behavior of navigating to a new web page
         window.addEventListener("dragover", e => e.preventDefault(), false);
-        document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
+        // document.addEventListener("pointermove", action(e => SearchBox.Instance._undoBackground = UndoManager.batchCounter ? "#000000a8" : undefined));
         document.addEventListener("pointerdown", this.globalPointerDown);
         document.addEventListener("click", (e: MouseEvent) => {
             if (!e.cancelBubble) {
@@ -405,22 +406,26 @@ export class MainView extends React.Component {
     }
 
     @computed get mainInnerContent() {
+        const width = this.propertiesWidth() + this._flyoutWidth + this.menuPanelWidth();
+        const transform = this._flyoutWidth ? 'translate(-28px, 0px)' : undefined;
         return <>
             {this.menuPanel}
             <div key="inner" className={`mainView-innerContent${this.darkScheme ? "-dark" : ""}`}>
                 {this.flyout}
-                <div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined, left: this._flyoutWidth ? (this._flyoutWidth + this.menuPanelWidth() - 10) : -10 }} onPointerDown={this.onFlyoutPointerDown} >
+                <div className="mainView-libraryHandle" style={{ display: !this._flyoutWidth ? "none" : undefined }} onPointerDown={this.onFlyoutPointerDown} >
                     <FontAwesomeIcon icon="chevron-left" color={this.darkScheme ? "white" : "black"} style={{ opacity: "50%" }} size="sm" />
                 </div>
-                <div className="mainView-innerContainer" style={{ width: `calc(100% - ${this.propertiesWidth() + this._flyoutWidth + this.menuPanelWidth()}px)` }}>
+                <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)`, transform: transform }}>
                     <CollectionMenu />
 
                     {this.dockingContent}
 
-                    <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this.propertiesWidth() - 1 }}>
-                        <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? "white" : "black"} size="sm" />
+                    <div className="mainView-propertiesDragger" key="props" onPointerDown={this.onPropertiesPointerDown} style={{ right: this._flyoutWidth ? 0 : this.propertiesWidth() - 1 }}>
+                        <FontAwesomeIcon icon={this.propertiesWidth() < 10 ? "chevron-left" : "chevron-right"} color={this.darkScheme ? Colors.WHITE : Colors.BLACK} size="sm" />
+                    </div>
+                    <div className="properties-container">
+                        {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.getContentsHeight()} />}
                     </div>
-                    {this.propertiesWidth() < 10 ? (null) : <PropertiesView styleProvider={DefaultStyleProvider} width={this.propertiesWidth()} height={this.getContentsHeight()} />}
                 </div>
             </div>
         </>;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 4df3e4f00..8136edf04 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -24,7 +24,7 @@ import { EditableView } from "./EditableView";
 import { InkStrokeProperties } from "./InkStrokeProperties";
 import { DocumentView, StyleProviderFunc } from "./nodes/DocumentView";
 import { KeyValueBox } from "./nodes/KeyValueBox";
-import { PresBox } from "./nodes/PresBox";
+import { PresBox } from "./nodes/trails/PresBox";
 import { PropertiesButtons } from "./PropertiesButtons";
 import { PropertiesDocContextSelector } from "./PropertiesDocContextSelector";
 import "./PropertiesView.scss";
diff --git a/src/client/views/_nodeModuleOverrides.scss b/src/client/views/_nodeModuleOverrides.scss
index cb59489c0..140be2140 100644
--- a/src/client/views/_nodeModuleOverrides.scss
+++ b/src/client/views/_nodeModuleOverrides.scss
@@ -58,12 +58,10 @@ div .lm_header {
 .lm_header .lm_controls {
     align-items: center;
     position: absolute;
-    background-color: #000000;
+    background-color: $dark-gray;
     border-radius: 5px;
     display: flex;
-    top: 2px;
     justify-content: space-evenly;
-    right: 2px;
     height: 18px;
     width: 65px;
 }
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index c0fc774d3..f04b19ef7 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -38,10 +38,10 @@
         border: unset;
 
         .collectionMenu-divider {
-            height: 85%;
+            height: 100%;
             margin-left: 3px;
             margin-right: 3px;
-            width: 1.5px;
+            width: 2px;
             background-color: $medium-gray;
         }
 
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 6e6fabd0d..a9b978c4e 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -29,7 +29,7 @@ import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
 import { DocumentView } from "../nodes/DocumentView";
 import { RichTextMenu } from "../nodes/formattedText/RichTextMenu";
-import { PresBox } from "../nodes/PresBox";
+import { PresBox } from "../nodes/trails/PresBox";
 import "./CollectionMenu.scss";
 import { CollectionViewType, COLLECTION_BORDER_WIDTH } from "./CollectionView";
 import { TabDocView } from "./TabDocView";
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 0e67bebd8..d82810652 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -25,7 +25,7 @@ import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from "../../util/UndoManager";
 import { LightboxView } from '../LightboxView';
 import { DocFocusOptions, DocumentView, DocumentViewProps } from "../nodes/DocumentView";
-import { PresBox, PinProps, PresMovement } from '../nodes/PresBox';
+import { PinProps, PresBox, PresMovement } from '../nodes/trails';
 import { DefaultLayerProvider, DefaultStyleProvider, StyleLayers, StyleProp } from '../StyleProvider';
 import { CollectionDockingView } from './CollectionDockingView';
 import { CollectionDockingViewMenu } from './CollectionDockingViewMenu';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a4e310e6c..c5f6f7bf2 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -38,7 +38,7 @@ import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDo
 import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment, ViewSpecPrefix } from "../../nodes/DocumentView";
 import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
 import { pageSchema } from "../../nodes/ImageBox";
-import { PresBox } from "../../nodes/PresBox";
+import { PresBox } from "../../nodes/trails/PresBox";
 import { StyleLayers, StyleProp } from "../../StyleProvider";
 import { CollectionDockingView } from "../CollectionDockingView";
 import { CollectionSubView } from "../CollectionSubView";
@@ -834,10 +834,10 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
                 map(doc => ({ ...this.childDataProvider(doc, ""), ...this.childSizeProvider(doc, "") }));
             if (measuredDocs.length) {
                 const ranges = measuredDocs.reduce(({ xrange, yrange }, { x, y, width, height }) =>  // computes range of content
-                ({
-                    xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
-                    yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
-                })
+                    ({
+                        xrange: { min: Math.min(xrange.min, x), max: Math.max(xrange.max, x + width) },
+                        yrange: { min: Math.min(yrange.min, y), max: Math.max(yrange.max, y + height) }
+                    })
                     , {
                         xrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE },
                         yrange: { min: Number.MAX_VALUE, max: -Number.MAX_VALUE }
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b1f2750c3..4fae961b1 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -19,7 +19,8 @@ import { Transform } from "../../../util/Transform";
 import { undoBatch, UndoManager } from "../../../util/UndoManager";
 import { ContextMenu } from "../../ContextMenu";
 import { FormattedTextBox } from "../../nodes/formattedText/FormattedTextBox";
-import { PresBox, PresMovement } from "../../nodes/PresBox";
+import { PresBox } from "../../nodes/trails/PresBox";
+import { PresMovement } from "../../nodes/trails/PresEnums";
 import { PreviewCursor } from "../../PreviewCursor";
 import { CollectionDockingView } from "../CollectionDockingView";
 import { SubCollectionViewProps } from "../CollectionSubView";
diff --git a/src/client/views/global/globalCssVariables.scss b/src/client/views/global/globalCssVariables.scss
index a8d4235bd..72adc171b 100644
--- a/src/client/views/global/globalCssVariables.scss
+++ b/src/client/views/global/globalCssVariables.scss
@@ -38,6 +38,9 @@ $antimodemenu-height: 36px;
 $contextMenu-zindex: 100000; // context menu shows up over everything
 $radialMenu-zindex: 100000; // context menu shows up over everything
 
+// borders
+$standard-border: solid 1px #9F9F9F;
+
 $searchpanel-height: 32px;
 $mainTextInput-zindex: 999; // then text input overlay so that it's context menu will appear over decorations, etc
 $docDecorations-zindex: 998; // then doc decorations appear over everything else
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 9b75cd8f9..3d2cdf5a4 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -11,7 +11,7 @@ import { CollectionFreeFormView } from "../collections/collectionFreeForm/Collec
 import { CollectionSchemaView } from "../collections/collectionSchema/CollectionSchemaView";
 import { CollectionView } from "../collections/CollectionView";
 import { InkingStroke } from "../InkingStroke";
-import { PresElementBox } from "../presentationview/PresElementBox";
+import { PresElementBox } from "../nodes/trails/PresElementBox";
 import { SearchBox } from "../search/SearchBox";
 import { DashWebRTCVideo } from "../webcam/DashWebRTCVideo";
 import { YoutubeBox } from "./../../apis/youtube/YoutubeBox";
@@ -32,7 +32,7 @@ import { LabelBox } from "./LabelBox";
 import { LinkAnchorBox } from "./LinkAnchorBox";
 import { LinkBox } from "./LinkBox";
 import { PDFBox } from "./PDFBox";
-import { PresBox } from "./PresBox";
+import { PresBox } from "./trails/PresBox";
 import { ScreenshotBox } from "./ScreenshotBox";
 import { ScriptingBox } from "./ScriptingBox";
 import { SliderBox } from "./SliderBox";
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 60fa462ad..80a014926 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -43,7 +43,7 @@ import { DocumentLinksButton } from './DocumentLinksButton';
 import "./DocumentView.scss";
 import { LinkAnchorBox } from './LinkAnchorBox';
 import { LinkDocPreview } from "./LinkDocPreview";
-import { PresBox } from './PresBox';
+import { PresBox } from './trails/PresBox';
 import { RadialMenu } from './RadialMenu';
 import React = require("react");
 import { ScriptingBox } from "./ScriptingBox";
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 6ae4b9726..0d415e238 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -14,6 +14,7 @@ import { DocComponent } from '../DocComponent';
 import { StyleProp } from '../StyleProvider';
 import { FieldView, FieldViewProps } from './FieldView';
 import './FontIconBox.scss';
+import { Colors } from '../global/globalEnums';
 const FontIconSchema = createSchema({
     icon: "string",
 });
@@ -47,7 +48,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
         const icon = StrCast(this.dataDoc.icon, "user") as any;
         const presSize = shape === 'round' ? 25 : 30;
         const presTrailsIcon = <img src={`/assets/${"presTrails.png"}`}
-            style={{ width: presSize, height: presSize, filter: `invert(${color === "white" ? "100%" : "0%"})`, marginBottom: "5px" }} />;
+            style={{ width: presSize, height: presSize, filter: `invert(${color === Colors.DARK_GRAY ? "0%" : "100%"})`, marginBottom: "5px" }} />;
         const button = <button className={`menuButton-${shape}`} onContextMenu={this.specificContextMenu}
             style={{ backgroundColor: backgroundColor, }}>
             <div className="menuButton-wrap">
diff --git a/src/client/views/nodes/PresBox.scss b/src/client/views/nodes/PresBox.scss
deleted file mode 100644
index 5d1c5f4eb..000000000
--- a/src/client/views/nodes/PresBox.scss
+++ /dev/null
@@ -1,1243 +0,0 @@
-@import "../global/globalCssVariables";
-
-.presBox-cont {
-    cursor: auto;
-    position: absolute;
-    display: block;
-    pointer-events: inherit;
-    z-index: 2;
-    font-family: Roboto;
-    width: 100%;
-    min-width: 20px;
-    height: 100%;
-    min-height: 35px;
-    letter-spacing: 2px;
-    overflow: hidden;
-    transition: 0.7s opacity ease;
-
-    .presBox-listCont {
-        position: relative;
-        height: calc(100% - 67px);
-        width: 100%;
-    }
-
-    .presBox-toolbar-dropdown {
-        border-radius: 5px;
-        background-color: white;
-        transform: translate(8px, -5px);
-        box-shadow: 1px 1px 4px 4px rgba(0, 0, 0, 0.25);
-        z-index: 1000;
-        width: calc(100% - 50px);
-        height: max-content;
-        justify-self: center;
-        letter-spacing: normal;
-        height: max-content;
-        font-weight: 500;
-        position: relative;
-        font-size: 13;
-    }
-
-    .presBox-toolbar {
-        position: relative;
-        display: inline-flex;
-        align-items: center;
-        height: 30px;
-        width: 100%;
-        color: $white;
-        background-color: $dark-gray;
-
-        .toolbar-button {
-            cursor: pointer;
-            margin-left: 10px;
-            margin-right: 10px;
-            letter-spacing: 0;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            transition: 0.5s;
-        }
-
-        .toolbar-button.active {
-            color: $light-blue;
-            background-color: white;
-            border-radius: 100%;
-        }
-
-        .toolbar-transitionButtons {
-            display: block;
-
-            .toolbar-transition {
-                display: flex;
-                font-size: 10;
-                width: 100;
-                background-color: rgba(0, 0, 0, 0);
-                min-width: max-content;
-
-                .toolbar-icon {
-                    margin-right: 5px;
-                }
-            }
-        }
-    }
-
-    .toolbar-moreInfo {
-        position: absolute;
-        right: 5px;
-        display: flex;
-        width: max-content;
-        height: 25px;
-        justify-content: center;
-        transform: rotate(90deg);
-        align-items: center;
-        transition: 0.7s ease;
-
-        .toolbar-moreInfoBall {
-            width: 4px;
-            height: 4px;
-            border-radius: 100%;
-            background-color: white;
-            margin: 1px;
-            position: relative;
-        }
-    }
-
-    .toolbar-moreInfo.active {
-        transform: rotate(0deg);
-    }
-
-    .toolbar-divider {
-        border-left: solid $medium-gray 0.5px;
-        height: 20px;
-    }
-}
-
-.dropdown {
-    font-size: 10;
-    margin-left: 5px;
-    color: $medium-gray;
-    transition: 0.5s ease;
-}
-
-.dropdown.active {
-    transform: rotate(180deg);
-    color: $light-blue;
-    opacity: 0.8;
-}
-
-.presBox-radioButtons {
-    font-size: 10px;
-    font-weight: 200;
-    // background-color: rgba(0, 0, 0, 0.1);
-
-    .checkbox-container {
-        margin-left: 10px;
-        display: inline-flex;
-        width: 100%;
-        height: 20px;
-        align-items: center;
-    }
-
-    .checkbox-dropdown {
-        display: flex;
-        width: 100%;
-        align-items: flex-end;
-        gap: 5px;
-
-        .presBox-viewPicker {
-            width: calc(100% - 120px);
-            min-width: 30px;
-        }
-    }
-}
-
-.presBox-ribbon {
-    position: relative;
-    display: inline;
-    font-family: Roboto;
-    z-index: 100;
-    transition: 0.7s;
-
-    .ribbon-doubleButton {
-        display: inline-flex;
-    }
-
-    .presBox-reactiveGrid {
-        display: grid;
-        justify-content: flex-start;
-        align-items: center;
-        grid-template-columns: repeat(auto-fit, 70px);
-    }
-
-    .ribbon-colorBox {
-        cursor: pointer;
-        border: solid 1px $black;
-        display: flex;
-        margin-left: 5px;
-        margin-top: 5px;
-        margin-bottom: 5px;
-        justify-content: center;
-        align-items: center;
-        height: 15px;
-        width: 15px;
-        padding: 0px;
-        transform: translate(2px, 3px);
-    }
-
-    .ribbon-property {
-        font-size: 11;
-        font-weight: 200;
-        height: 20;
-        background-color: $white;
-        color: $black;
-        border: solid 1px $black;
-        display: flex;
-        margin-left: 5px;
-        margin-top: 5px;
-        margin-bottom: 5px;
-        width: max-content;
-        justify-content: center;
-        align-items: center;
-        padding-right: 10px;
-        padding-left: 10px;
-    }
-
-    .ribbon-propertyUpDown {
-        height: 20;
-        width: 20;
-        margin-top: 5px;
-        display: grid;
-        grid-template-rows: 10px 10px;
-
-        .ribbon-propertyUpDownItem {
-            cursor: pointer;
-            color: white;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            height: 100%;
-            width: 100%;
-            background: $black;
-        }
-
-        .ribbon-propertyUpDownItem:hover {
-            background: $medium-gray;
-            transform: scale(1.05);
-        }
-    }
-
-    .presBox-subheading {
-        font-size: 11;
-        font-weight: 400;
-        margin-top: 10px;
-    }
-
-    @media screen and (-webkit-min-device-pixel-ratio:0) {
-
-        .multiThumb-slider {
-            display: grid;
-            background-color: $white;
-            height: 10px;
-            border-radius: 10px;
-            overflow: hidden;
-
-            .toolbar-slider {
-                margin-top: 0px;
-                background: none;
-                -webkit-appearance: none;
-                pointer-events: none;
-            }
-
-            .toolbar-slider.start::-webkit-slider-thumb {
-                width: 10px;
-                pointer-events: auto;
-                -webkit-appearance: none;
-                height: 10px;
-                cursor: ew-resize;
-                background: $medium-blue;
-                box-shadow: -100vw 0 0 100vw $white;
-            }
-
-            .toolbar-slider.end::-webkit-slider-thumb {
-                width: 10px;
-                pointer-events: auto;
-                -webkit-appearance: none;
-                height: 10px;
-                cursor: ew-resize;
-                background: $medium-blue;
-                box-shadow: -100vw 0 0 100vw $light-blue;
-            }
-        }
-
-        .toolbar-slider {
-            margin-top: 5px;
-            position: relative;
-            align-self: center;
-            justify-self: left;
-            overflow: hidden;
-            width: 100%;
-            height: 10px;
-            border-radius: 10px;
-            -webkit-appearance: none;
-            background-color: $white;
-        }
-
-        .toolbar-slider:focus {
-            outline: none;
-        }
-
-        .toolbar-slider::-webkit-slider-runnable-track {
-            height: 10px;
-            -webkit-appearance: none;
-            margin-top: -1px;
-        }
-
-        .toolbar-slider::-webkit-slider-thumb {
-            width: 10px;
-            pointer-events: auto;
-            -webkit-appearance: none;
-            height: 10px;
-            cursor: ew-resize;
-            background: $medium-blue;
-            box-shadow: -100vw 0 0 100vw $light-blue;
-        }
-
-        .presBox-checkbox {
-            -webkit-appearance: none;
-            -webkit-user-select: none;
-            -moz-user-select: none;
-            -ms-user-select: none;
-            user-select: none;
-            margin: 0;
-            margin-right: 3px;
-            border-radius: 100%;
-            height: 15px;
-            width: 15px;
-            min-width: 15px;
-            cursor: pointer;
-            background: $white;
-        }
-
-        .presBox-checkbox:focus {
-            outline: none;
-        }
-
-        .presBox-checkbox:hover {
-            background: $light-gray;
-        }
-
-        .presBox-checkbox:checked {
-            background: $light-blue;
-        }
-    }
-
-
-
-    .slider-headers {
-        position: relative;
-        display: grid;
-        justify-content: space-between;
-        width: 100%;
-        height: max-content;
-        grid-template-columns: auto auto auto;
-        grid-template-rows: max-content;
-        font-weight: 100;
-        margin-top: 3px;
-        font-size: 10px;
-
-        .slider-block {
-            width: 63px;
-            border-radius: 5px;
-            text-align: center;
-            margin-bottom: 8px;
-            margin-top: 8px;
-        }
-
-        .slider-number {
-            border-radius: 3px;
-            width: 30px;
-            margin: auto;
-        }
-    }
-
-    .slider-value {
-        top: -20;
-        color: #2f86a2;
-        position: absolute;
-    }
-
-    .slider-value.none,
-    .slider-headers.none,
-    .toolbar-slider.none {
-        display: none;
-    }
-
-    .dropdown-header {
-        padding-bottom: 10px;
-        font-weight: 800;
-        text-align: center;
-        font-size: 16;
-        width: 90%;
-        color: $black;
-        transform: translate(5%, 0px);
-        border-bottom: solid 2px $medium-gray;
-    }
-
-
-    .ribbon-textInput {
-        border-radius: 2px;
-        height: 20px;
-        font-size: 11.5;
-        font-weight: 100;
-        align-self: center;
-        justify-self: left;
-        margin-top: 5px;
-        padding-left: 10px;
-        background-color: $white;
-        border: solid 1px $black;
-        min-width: 80px;
-        max-width: 200px;
-        width: 100%;
-    }
-
-    .presBox-input {
-        width: 30;
-        height: 100%;
-        background: none;
-        border: none;
-        text-align: right;
-    }
-
-    .presBox-input:focus {
-        outline: none;
-    }
-
-    .ribbon-frameSelector {
-        border: $black solid 1px;
-        width: 60px;
-        height: 20px;
-        margin-top: 5px;
-        display: grid;
-        grid-template-columns: auto 27px auto;
-        position: relative;
-        border-radius: 5px;
-        overflow: hidden;
-        align-items: center;
-        justify-self: left;
-
-        .fwdKeyframe,
-        .backKeyframe {
-            cursor: pointer;
-            position: relative;
-            height: 100%;
-            background: $white;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            text-align: center;
-            color: $black;
-        }
-
-        .numKeyframe {
-            cursor: pointer;
-            font-size: 10;
-            font-weight: 600;
-            position: relative;
-            color: $black;
-            display: flex;
-            width: 100%;
-            height: 100%;
-            text-align: center;
-            align-items: center;
-            justify-content: center;
-        }
-    }
-
-    .ribbon-final-box {
-        align-self: flex-start;
-        justify-self: center;
-        display: grid;
-        margin-top: 10px;
-        grid-template-rows: auto auto;
-        /* padding-left: 10px; */
-        /* padding-right: 10px; */
-        letter-spacing: normal;
-        min-width: max-content;
-        width: 100%;
-        font-size: 13;
-        font-weight: 500;
-        position: relative;
-
-
-        .ribbon-final-button {
-            cursor: pointer;
-            position: relative;
-            font-size: 11;
-            font-weight: normal;
-            letter-spacing: normal;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            margin-bottom: 5px;
-            height: 25px;
-            color: white;
-            width: 100%;
-            max-width: 120;
-            padding-left: 10;
-            padding-right: 10;
-            border-radius: 10px;
-            background-color: $medium-gray;
-        }
-
-        .ribbon-final-button:hover {
-            transform: scale(1.05);
-            transition: all 0.4s;
-        }
-
-        .ribbon-final-button-hidden {
-            cursor: pointer;
-            position: relative;
-            font-size: 11;
-            font-weight: normal;
-            letter-spacing: normal;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            margin-bottom: 5px;
-            height: 25px;
-            color: $light-gray;
-            width: 100%;
-            max-width: 120;
-            padding-left: 10;
-            padding-right: 10;
-            border-radius: 10px;
-            background-color: $black;
-        }
-
-        .ribbon-final-button-hidden:hover {
-            transform: scale(1.05);
-            transition: all 0.4s;
-        }
-
-        .ribbon-frameList {
-            width: calc(100% - 5px);
-            height: 50px;
-            background-color: $white;
-            border: 1px solid $medium-gray;
-            grid-template-rows: max-content;
-
-            .frameList-header {
-                display: grid;
-                width: 100%;
-                height: 20px;
-                background-color: $medium-gray;
-
-                .frameList-headerButtons {
-                    display: flex;
-                    grid-column: 7;
-                    width: 60px;
-                    justify-self: right;
-                    justify-content: flex-end;
-
-                    .headerButton {
-                        cursor: pointer;
-                        position: relative;
-                        border-radius: 100%;
-                        z-index: 300;
-                        width: 15px;
-                        height: 15px;
-                        display: flex;
-                        font-size: 10px;
-                        justify-self: center;
-                        align-self: center;
-                        background-color: rgba(0, 0, 0, 0.5);
-                        color: white;
-                        justify-content: center;
-                        align-items: center;
-                        transition: 0.2s;
-                        margin-right: 3px;
-                    }
-
-                    .headerButton:hover {
-                        background-color: rgba(0, 0, 0, 1);
-                        transform: scale(1.15);
-                    }
-                }
-            }
-        }
-    }
-
-    .selectedList {
-        display: block;
-        min-width: 50;
-        max-width: 120;
-        height: 70;
-        overflow-y: scroll;
-
-        .selectedList-items {
-            font-size: 7;
-            font-weight: normal;
-        }
-    }
-
-    .ribbon-button {
-        cursor: pointer;
-        font-size: 10.5;
-        font-weight: 300;
-        height: 20;
-        background-color: $medium-gray;
-        color: white;
-        display: flex;
-        margin-top: 5px;
-        margin-bottom: 5px;
-        border-radius: 5px;
-        margin-right: 5px;
-        width: max-content;
-        justify-content: center;
-        align-items: center;
-        padding-right: 10px;
-        padding-left: 10px;
-    }
-
-    .ribbon-button:hover {
-        transform: scale(1.03);
-        transition: all 0.4s;
-        font-weight: 400;
-        opacity: 1;
-        color: $white;
-        background-color: $black;
-    }
-
-    .ribbon-toggle {
-        cursor: pointer;
-        font-size: 10.5;
-        font-weight: 200;
-        height: 20;
-        background-color: $white;
-        border: solid 1px rgba(0, 0, 0, 0.5);
-        display: flex;
-        color: $black;
-        margin-top: 5px;
-        margin-bottom: 5px;
-        border-radius: 5px;
-        margin-right: 5px;
-        width: max-content;
-        justify-content: center;
-        align-items: center;
-        padding-right: 10px;
-        padding-left: 10px;
-    }
-
-    .ribbon-toggle.active {
-        background-color: #aedef8;
-    }
-
-    .ribbon-toggle:hover {
-        transform: scale(1.03);
-        transition: all 0.4s;
-        border: solid 1px rgba(0, 0, 0, 0.75);
-    }
-
-    svg.svg-inline--fa.fa-thumbtack.fa-w-12.toolbar-thumbtack {
-        right: 40;
-        position: absolute;
-        transform: rotate(45deg);
-    }
-
-    .ribbon-box {
-        display: grid;
-        grid-template-rows: max-content auto;
-        justify-self: center;
-        margin-top: 10px;
-        padding-right: 10px;
-        letter-spacing: normal;
-        width: 100%;
-        height: max-content;
-        font-weight: 500;
-        position: relative;
-        font-size: 13;
-        padding-bottom: 10px;
-        border-bottom: solid 1px $dark-gray;
-
-        .presBox-dropdown:hover {
-            border: solid 1px $medium-blue;
-
-            .presBox-dropdownIcon {
-                color: $medium-blue;
-            }
-        }
-
-        .presBox-dropdown {
-            cursor: pointer;
-            display: grid;
-            grid-template-columns: auto 20%;
-            position: relative;
-            border: solid 1px $black;
-            background-color: $light-gray;
-            border-radius: 5px;
-            font-size: 10;
-            height: 25;
-            color: $black;
-            padding-left: 5px;
-            align-items: center;
-            margin-top: 5px;
-            margin-bottom: 5px;
-            font-weight: 200;
-            width: 100%;
-            min-width: max-content;
-            max-width: 200px;
-            overflow: visible;
-
-
-            .presBox-dropdownOption {
-                cursor: pointer;
-                font-size: 11;
-                display: block;
-                padding-left: 10px;
-                padding-right: 5px;
-                padding-top: 3;
-                padding-bottom: 3;
-            }
-
-            .presBox-dropdownOption:hover {
-                position: relative;
-                background-color: lightgrey;
-            }
-
-            .presBox-dropdownOption.active {
-                position: relative;
-                background-color: $light-blue;
-            }
-
-            .presBox-dropdownOptions {
-                position: absolute;
-                top: 23px;
-                left: -2px;
-                z-index: 200;
-                width: 85%;
-                min-width: max-content;
-                display: block;
-                background: #FFFFFF;
-                border: 0.5px solid #979797;
-                box-sizing: border-box;
-                box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
-            }
-
-            .presBox-dropdownIcon {
-                position: relative;
-                color: black;
-                align-self: center;
-                justify-self: center;
-                margin-right: 2px;
-            }
-        }
-    }
-}
-
-.presBox-ribbon.active {
-    display: grid;
-    grid-template-columns: auto auto auto auto auto;
-    grid-template-rows: 100%;
-    height: 100px;
-    padding-top: 5px;
-    padding-bottom: 5px;
-    border: solid 1px $black;
-    // overflow: auto; 
-
-    ::-webkit-scrollbar {
-        -webkit-appearance: none;
-        height: 3px;
-        width: 8px;
-    }
-
-    ::-webkit-scrollbar-thumb {
-        border-radius: 2px;
-    }
-}
-
-.dropdown-play-button {
-    cursor: pointer;
-    font-size: 12;
-    padding-left: 5px;
-    padding-right: 5px;
-    padding-top: 5px;
-    padding-bottom: 5px;
-    text-align: left;
-    justify-content: left;
-}
-
-.dropdown-play-button:hover {
-    background-color: lightgrey;
-}
-
-.presBox-button-left {
-    cursor: pointer;
-    position: relative;
-    align-self: flex-start;
-    justify-self: flex-start;
-    width: 100%;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    border-radius: 4px;
-    padding-left: 7px;
-    padding-right: 7px;
-    border-bottom-right-radius: 0;
-    border-top-right-radius: 0;
-}
-
-.presBox-button-right {
-    cursor: pointer;
-    position: relative;
-    text-align: center;
-    border-left: solid 1px $medium-gray;
-    width: 20%;
-    height: 100%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    border-radius: 4px;
-    padding-left: 7px;
-    padding-right: 7px;
-    border-bottom-left-radius: 0;
-    border-top-left-radius: 0;
-}
-
-.presBox-button-right.active {
-    background-color: #223063;
-    border: #aedcf6 solid 1px;
-    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
-}
-
-.dropdown-play {
-    cursor: pointer;
-    right: 0px;
-    top: calc(100% + 2px);
-    display: none;
-    border-radius: 5px;
-    width: max-content;
-    min-height: 20px;
-    height: max-content;
-    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
-    z-index: 200;
-    background-color: white;
-    color: $black;
-    position: absolute;
-    overflow: hidden;
-}
-
-.dropdown-play.active {
-    display: block;
-}
-
-.open-layout {
-    cursor: pointer;
-    position: relative;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    transform: translate(0px, -1px);
-    background-color: $white;
-    width: 40px;
-    height: 15px;
-    align-self: center;
-    justify-self: center;
-    border: solid 1px $black;
-    border-top: 0px;
-    border-bottom-right-radius: 7px;
-    border-bottom-left-radius: 7px;
-}
-
-.layout-container {
-    padding: 5px;
-    display: grid;
-    background-color: $white;
-    grid-template-columns: repeat(auto-fit, minmax(90px, 100px));
-    width: 100%;
-    border: solid 1px $black;
-    min-width: 100px;
-    overflow: hidden;
-
-    .layout:hover {
-        border: solid 2px $medium-blue;
-    }
-
-    .layout {
-        cursor: pointer;
-        align-self: center;
-        justify-self: center;
-        margin-top: 5;
-        margin-bottom: 5;
-        position: relative;
-        height: 55px;
-        min-width: 90px;
-        width: 90px;
-        overflow: hidden;
-        background-color: white;
-        border: solid $medium-gray 1px;
-        display: grid;
-        grid-template-rows: auto;
-        align-items: center;
-        text-align: center;
-
-        .title {
-            position: relative;
-            align-self: end;
-            padding-left: 3px;
-            margin-left: 3px;
-            margin-right: 3px;
-            height: 13;
-            font-size: 12;
-            display: flex;
-            background-color: #white;
-        }
-
-        .subtitle {
-            align-self: flex-start;
-            position: relative;
-            padding-left: 3px;
-            margin-left: 3px;
-            margin-right: 3px;
-            font-weight: 400;
-            height: 13;
-            font-size: 9;
-            display: flex;
-            background-color: $white;
-        }
-
-        .content {
-            position: relative;
-            font-weight: 200;
-            align-self: flex-start;
-            padding-left: 3px;
-            margin-left: 3px;
-            margin-right: 3px;
-            height: 13;
-            font-size: 10;
-            display: flex;
-            background-color: $white;
-            height: 33;
-            text-align: left;
-            font-size: 8px;
-        }
-    }
-}
-
-.presBox-buttons {
-    position: relative;
-    width: 100%;
-    background: gray;
-    min-height: 35px;
-    padding-top: 5px;
-    padding-bottom: 5px;
-    display: grid;
-    grid-template-columns: auto auto;
-
-    .presBox-viewPicker {
-        cursor: pointer;
-        height: 25;
-        position: relative;
-        display: inline-block;
-        grid-column: 1;
-        border-radius: 5px;
-        min-width: 15px;
-        max-width: 100px;
-        left: 8px;
-    }
-
-    .presBox-presentPanel {
-        display: flex;
-        justify-self: end;
-        width: 100%;
-        max-width: 300px;
-        min-width: 150px;
-    }
-
-
-
-    select {
-        background: $dark-gray;
-        color: $white;
-    }
-
-    .presBox-button {
-        cursor: pointer;
-        height: 25px;
-        border-radius: 5px;
-        display: none;
-        justify-content: center;
-        align-content: center;
-        align-items: center;
-        text-align: center;
-        letter-spacing: normal;
-        width: inherit;
-        background: $dark-gray;
-        color: $white;
-    }
-
-    .presBox-button.active {
-        display: flex;
-    }
-
-    .presBox-button.active:hover {
-        background-color: $medium-blue;
-    }
-
-    .presBox-button.edit {
-        display: flex;
-        max-width: 25px;
-    }
-
-    .presBox-button.present {
-        display: flex;
-        width: max-content;
-        position: absolute;
-        right: 10px;
-
-        .present-icon {
-            margin-right: 7px;
-        }
-    }
-
-
-
-    .collectionViewBaseChrome-viewPicker {
-        min-width: 50;
-        width: 5%;
-        height: 25;
-        position: relative;
-        display: inline-block;
-        left: 8px;
-    }
-}
-
-.presBox-backward,
-.presBox-forward {
-    width: 25px;
-    border-radius: 5px;
-    top: 50%;
-    position: absolute;
-    display: inline-block;
-}
-
-.presBox-backward {
-    left: 5;
-}
-
-.presBox-forward {
-    right: 5;
-}
-
-// CSS adjusted for mobile devices
-@media only screen and (max-device-width: 480px) {
-    .presBox-cont .presBox-buttons {
-        position: absolute;
-        top: 70%;
-        left: 50%;
-        transform: translate(-50%, 0);
-        width: max-content;
-        height: 15%;
-        z-index: 2;
-        align-items: center;
-        background: rgba(0, 0, 0, 0);
-        display: inline-flex;
-
-        .presBox-button {
-            margin-top: 5%;
-            height: 250;
-            width: 300;
-            font-size: 100;
-            display: flex;
-            align-items: center;
-            background: $dark-gray;
-            color: $white;
-        }
-
-        .presBox-viewPicker {
-            top: -70;
-            left: 2.5%;
-            height: 50;
-            width: 95%;
-            font-size: 30px;
-            position: absolute;
-            min-width: 50px;
-        }
-    }
-
-    .presBox-cont .presBox-listCont {
-        top: 50;
-        height: calc(100% - 80px);
-    }
-
-    .input,
-    .select {
-        font-size: 100%;
-    }
-}
-
-.miniPres {
-    cursor: grab;
-    position: absolute;
-    right: 10;
-    top: 10;
-    opacity: 0.1;
-    transition: all 0.4s;
-    color: $white;
-}
-
-.miniPres:hover {
-    opacity: 1;
-}
-
-.presPanelOverlay {
-    background-color: $dark-gray;
-    color: $white;
-    border-radius: 5px;
-    grid-template-rows: 100%;
-    height: 25;
-    width: max-content;
-    min-width: max-content;
-    justify-content: space-evenly;
-    align-items: center;
-    display: flex;
-    position: absolute;
-    right: 10px;
-    transition: all 0.2s;
-
-    .presPanel-button-text {
-        cursor: pointer;
-        display: flex;
-        height: 20;
-        width: max-content;
-        font-family: Roboto;
-        font-weight: 400;
-        margin-left: 3px;
-        margin-right: 3px;
-        padding-right: 3px;
-        padding-left: 3px;
-        letter-spacing: normal;
-        border-radius: 5px;
-        align-items: center;
-        justify-content: center;
-        transition: all 0.3s;
-    }
-
-    .presPanel-divider {
-        width: 0.5px;
-        height: 80%;
-        border-right: solid 1px $medium-gray;
-    }
-
-    .presPanel-button-frame {
-        justify-self: center;
-        align-self: center;
-        align-items: center;
-        display: grid;
-        grid-template-columns: auto auto auto;
-        justify-content: space-around;
-        font-size: 11;
-        margin-left: 7;
-        width: 30;
-        height: 85%;
-        background-color: rgba(91, 157, 221, 0.4);
-        border-radius: 5px;
-    }
-
-    .presPanel-button {
-        cursor: pointer;
-        display: flex;
-        height: 20;
-        min-width: 20;
-        margin-left: 3px;
-        margin-right: 3px;
-        border-radius: 100%;
-        align-items: center;
-        justify-content: center;
-        transition: all 0.3s;
-    }
-
-    .presPanel-button:hover {
-        background-color: $medium-gray;
-        transform: scale(1.2);
-    }
-
-    .presPanel-button-text:hover {
-        background-color: $medium-gray;
-    }
-
-
-}
-
-// .miniPres {
-//     cursor: grab;
-//     position: absolute;
-//     overflow: hidden;
-//     right: 10;
-//     top: 10;
-//     opacity: 0.1;
-//     transition: all 0.4s;
-//     /* border: solid 1px; */
-//     color: white;
-//     /* box-shadow: black 0.4vw 0.4vw 0.8vw; */
-
-//     .miniPresOverlay {
-//         display: grid;
-//         grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
-//         grid-template-rows: 100%;
-//         height: 100%;
-//         justify-items: center;
-//         align-items: center;
-
-//         .miniPres-button-text {
-//             cursor: pointer;
-//             display: flex;
-//             height: 20;
-//             font-weight: 400;
-//             min-width: 100%;
-//             border-radius: 5px;
-//             align-items: center;
-//             justify-content: center;
-//             transition: all 0.3s;
-//         }
-
-//         .miniPres-button-frame {
-//             justify-self: center;
-//             align-self: center;
-//             align-items: center;
-//             display: grid;
-//             grid-template-columns: auto auto auto;
-//             justify-content: space-around;
-//             font-size: 11;
-//             margin-left: 7;
-//             width: 30;
-//             height: 85%;
-//             background-color: rgba(91, 157, 221, 0.4);
-//             border-radius: 5px;
-//         }
-
-//         .miniPres-divider {
-//             width: 0.5px;
-//             height: 80%;
-//             border-right: solid 2px #5a5a5a;
-//         }
-
-//         .miniPres-button {
-//             cursor: pointer;
-//             display: flex;
-//             height: 20;
-//             min-width: 20;
-//             border-radius: 100%;
-//             align-items: center;
-//             justify-content: center;
-//             transition: all 0.3s;
-//         }
-
-//         .miniPres-button:hover {
-//             background-color: #5a5a5a;
-//         }
-
-//         .miniPres-button-text:hover {
-//             background-color: #5a5a5a;
-//         }
-//     }
-// }
\ No newline at end of file
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
deleted file mode 100644
index f3fb6ff17..000000000
--- a/src/client/views/nodes/PresBox.tsx
+++ /dev/null
@@ -1,2472 +0,0 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
-import { observer } from "mobx-react";
-import { ColorState, SketchPicker } from "react-color";
-import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
-import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../fields/Doc";
-import { documentSchema } from "../../../fields/documentSchemas";
-import { InkTool } from "../../../fields/InkField";
-import { List } from "../../../fields/List";
-import { PrefetchProxy } from "../../../fields/Proxy";
-import { listSpec, makeInterface } from "../../../fields/Schema";
-import { ScriptField } from "../../../fields/ScriptField";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../fields/Types";
-import { returnFalse, returnOne, returnTrue, emptyFunction } from '../../../Utils';
-import { Docs } from "../../documents/Documents";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { DocumentManager } from "../../util/DocumentManager";
-import { Scripting } from "../../util/Scripting";
-import { SelectionManager } from "../../util/SelectionManager";
-import { undoBatch, UndoManager } from "../../util/UndoManager";
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionView, CollectionViewType } from "../collections/CollectionView";
-import { TabDocView } from "../collections/TabDocView";
-import { ViewBoxBaseComponent } from "../DocComponent";
-import { CollectionFreeFormDocumentView } from "./CollectionFreeFormDocumentView";
-import { FieldView, FieldViewProps } from './FieldView';
-import "./PresBox.scss";
-import Color = require("color");
-import { LightboxView } from "../LightboxView";
-
-export enum PresMovement {
-    Zoom = "zoom",
-    Pan = "pan",
-    Jump = "jump",
-    None = "none",
-}
-
-export enum PresEffect {
-    Zoom = "Zoom",
-    Lightspeed = "Lightspeed",
-    Fade = "Fade in",
-    Flip = "Flip",
-    Rotate = "Rotate",
-    Bounce = "Bounce",
-    Roll = "Roll",
-    None = "None",
-    Left = "left",
-    Right = "right",
-    Center = "center",
-    Top = "top",
-    Bottom = "bottom"
-}
-
-enum PresStatus {
-    Autoplay = "auto",
-    Manual = "manual",
-    Edit = "edit"
-}
-
-export enum PresColor {
-    LightBlue = "#AEDDF8",
-    DarkBlue = "#5B9FDD",
-    LightBackground = "#ececec",
-    SlideBackground = "#d5dce2",
-}
-
-export class PinProps {
-    audioRange?: boolean;
-    unpin?: boolean;
-    setPosition?: boolean;
-    hidePresBox?: boolean;
-}
-
-type PresBoxSchema = makeInterface<[typeof documentSchema]>;
-const PresBoxDocument = makeInterface(documentSchema);
-
-@observer
-export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>(PresBoxDocument) {
-    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
-
-    static renderEffectsDoc(renderDoc: any, layoutDoc: Doc) {
-        const effectProps = {
-            left: layoutDoc.presEffectDirection === PresEffect.Left,
-            right: layoutDoc.presEffectDirection === PresEffect.Right,
-            top: layoutDoc.presEffectDirection === PresEffect.Top,
-            bottom: layoutDoc.presEffectDirection === PresEffect.Bottom,
-            opposite: true,
-            delay: layoutDoc.presTransition,
-            // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
-        };
-        switch (layoutDoc.presEffect) {
-            case PresEffect.Zoom: return (<Zoom {...effectProps}>{renderDoc}</Zoom>);
-            case PresEffect.Fade: return (<Fade {...effectProps}>{renderDoc}</Fade>);
-            case PresEffect.Flip: return (<Flip {...effectProps}>{renderDoc}</Flip>);
-            case PresEffect.Rotate: return (<Rotate {...effectProps}>{renderDoc}</Rotate>);
-            case PresEffect.Bounce: return (<Bounce {...effectProps}>{renderDoc}</Bounce>);
-            case PresEffect.Roll: return (<Roll {...effectProps}>{renderDoc}</Roll>);
-            case PresEffect.Lightspeed: return (<LightSpeed {...effectProps}>{renderDoc}</LightSpeed>);
-            case PresEffect.None:
-            default: return renderDoc;
-        }
-    }
-    public static EffectsProvider(layoutDoc: Doc, renderDoc: any) {
-        return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ?
-            PresBox.renderEffectsDoc(renderDoc, layoutDoc)
-            :
-            renderDoc;
-    }
-
-    @observable public static Instance: PresBox;
-
-    @observable _isChildActive = false;
-    @observable _moveOnFromAudio: boolean = true;
-    @observable _presTimer!: NodeJS.Timeout;
-    @observable _presKeyEventsActive: boolean = false;
-
-    @observable _selectedArray: ObservableMap = new ObservableMap<Doc, any>();
-    @observable _eleArray: HTMLElement[] = [];
-    @observable _dragArray: HTMLElement[] = [];
-    @observable _pathBoolean: boolean = false;
-    @observable _expandBoolean: boolean = false;
-
-    private _disposers: { [name: string]: IReactionDisposer } = {};
-    @observable private transitionTools: boolean = false;
-    @observable private newDocumentTools: boolean = false;
-    @observable private progressivizeTools: boolean = false;
-    @observable private openMovementDropdown: boolean = false;
-    @observable private openEffectDropdown: boolean = false;
-    @observable private presentTools: boolean = false;
-    @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
-    @computed get tagDocs() {
-        const tagDocs: Doc[] = [];
-        for (const doc of this.childDocs) {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            tagDocs.push(tagDoc);
-        }
-        return tagDocs;
-    }
-    @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
-    @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); }
-    @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); }
-    @computed get scrollable(): boolean {
-        if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
-        else return false;
-    }
-    @computed get panable(): boolean {
-        if ((this.targetDoc.type === DocumentType.COL && this.targetDoc._viewType === CollectionViewType.Freeform) || this.targetDoc.type === DocumentType.IMG) return true;
-        else return false;
-    }
-    @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
-    constructor(props: any) {
-        super(props);
-        if (Doc.UserDoc().activePresentation = this.rootDoc) runInAction(() => PresBox.Instance = this);
-        if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
-            Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
-                title: "pres element template", type: DocumentType.PRESELEMENT, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"
-            }));
-            // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
-            // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
-            // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
-            // stored on each pres element.
-            (this.presElement as Doc).lookupField = ScriptField.MakeFunction("lookupPresBoxField(container, field, data)",
-                { field: "string", data: Doc.name, container: Doc.name });
-        }
-        this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
-    }
-    @computed get selectedDocumentView() {
-        if (SelectionManager.Views().length) return SelectionManager.Views()[0];
-        if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc);
-    }
-    @computed get isPres(): boolean {
-        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
-        if (this.selectedDoc?.type === DocumentType.PRES) {
-            document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
-            document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
-            return true;
-        }
-        return false;
-    }
-    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
-
-    @action
-    componentWillUnmount() {
-        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
-        this._presKeyEventsActive = false;
-        this.resetPresentation();
-        // Turn of progressivize editors
-        this.turnOffEdit(true);
-        Object.values(this._disposers).forEach(disposer => disposer?.());
-    }
-
-    @action
-    componentDidMount() {
-        this.rootDoc.presBox = this.rootDoc;
-        this.rootDoc._forceRenderEngine = "timeline";
-        this.layoutDoc.presStatus = PresStatus.Edit;
-        this.layoutDoc._gridGap = 0;
-        this.layoutDoc._yMargin = 0;
-        this.turnOffEdit(true);
-        DocListCastAsync((Doc.UserDoc().myPresentations as Doc).data).then(pres =>
-            !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc));
-        this._disposers.selection = reaction(() => SelectionManager.Views(),
-            views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation());
-    }
-
-    @action
-    updateCurrentPresentation = (pres?: Doc) => {
-        if (pres) Doc.UserDoc().activePresentation = pres;
-        else Doc.UserDoc().activePresentation = this.rootDoc;
-        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
-        document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
-        this._presKeyEventsActive = true;
-        PresBox.Instance = this;
-    }
-
-    // There are still other internal frames and should go through all frames before going to next slide
-    nextInternalFrame = (targetDoc: Doc, activeItem: Doc) => {
-        const currentFrame = Cast(targetDoc?._currentFrame, "number", null);
-        const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
-        targetDoc._viewTransition = "all 1s";
-        setTimeout(() => targetDoc._viewTransition = undefined, 1010);
-        this.nextKeyframe(targetDoc, activeItem);
-        if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc);
-        else targetDoc.keyFrameEditing = true;
-    }
-
-    _mediaTimer!: [NodeJS.Timeout, Doc];
-    // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
-    startTempMedia = (targetDoc: Doc, activeItem: Doc) => {
-        const duration: number = NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime);
-        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) {
-            const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
-            targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.presStartTime), NumCast(activeItem.presStartTime) + duration);
-        }
-        // if (targetDoc.type === DocumentType.AUDIO) {
-        //     if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
-        //     targetDoc._triggerAudio = NumCast(activeItem.presStartTime);
-        //     this._mediaTimer = [setTimeout(() => targetDoc._audioStop = true, duration * 1000), targetDoc];
-        // } else if (targetDoc.type === DocumentType.VID) {
-        //     targetDoc._triggerVideoStop = true;
-        //     setTimeout(() => targetDoc._currentTimecode = NumCast(activeItem.presStartTime), 10);
-        //     setTimeout(() => targetDoc._triggerVideo = true, 20);
-        //     this._mediaTimer = [setTimeout(() => targetDoc._triggerVideoStop = true, (duration * 1000) + 20), targetDoc];
-        // }
-    }
-
-    stopTempMedia = (targetDocField: FieldResult) => {
-        const targetDoc = Cast(targetDocField, Doc, null);
-        if (targetDoc?.type === DocumentType.AUDIO) {
-            if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
-            targetDoc._audioStop = true;
-        } else if (targetDoc?.type === DocumentType.VID) {
-            if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
-            targetDoc._triggerVideoStop = true;
-        }
-    }
-
-    // No more frames in current doc and next slide is defined, therefore move to next slide 
-    nextSlide = (activeNext: Doc) => {
-        const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
-        let nextSelected = this.itemIndex + 1;
-        this.gotoDocument(nextSelected, this.activeItem);
-        for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
-            if (!this.childDocs[nextSelected].groupWithUp) {
-                break;
-            } else {
-                console.log("Title: " + this.childDocs[nextSelected].title);
-                this.gotoDocument(nextSelected, this.activeItem, true);
-            }
-        }
-    }
-
-    // Called when the user activates 'next' - to move to the next part of the pres. trail
-    @action
-    next = () => {
-        const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const lastFrame = Cast(targetDoc?.lastFrame, "number", null);
-        const curFrame = NumCast(targetDoc?._currentFrame);
-        let internalFrames: boolean = false;
-        if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.scrollProgressivize) internalFrames = true;
-        if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) {
-            // Case 1: There are still other frames and should go through all frames before going to next slide
-            this.nextInternalFrame(targetDoc, activeItem);
-        } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
-            // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide 
-            this.nextSlide(activeNext);
-        } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
-            // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
-            this.gotoDocument(0, this.activeItem);
-        }
-    }
-
-    // Called when the user activates 'back' - to move to the previous part of the pres. trail
-    @action
-    back = () => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null);
-        const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
-        const lastFrame = Cast(targetDoc.lastFrame, "number", null);
-        const curFrame = NumCast(targetDoc._currentFrame);
-        let prevSelected = this.itemIndex;
-        // Functionality for group with up
-        let didZoom = activeItem.presMovement;
-        for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
-            didZoom = this.childDocs[prevSelected].presMovement;
-        }
-        if (lastFrame !== undefined && curFrame >= 1) {
-            // Case 1: There are still other frames and should go through all frames before going to previous slide
-            this.prevKeyframe(targetDoc, activeItem);
-        } else if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) {
-            // Case 2: There are no other frames so it should go to the previous slide
-            prevSelected = Math.max(0, prevSelected - 1);
-            this.gotoDocument(prevSelected, activeItem);
-            if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame);
-        } else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) {
-            // Case 3: Pres loop is on so it should go to the last slide
-            this.gotoDocument(this.childDocs.length - 1, activeItem);
-        }
-    }
-
-    //The function that is called when a document is clicked or reached through next or back.
-    //it'll also execute the necessary actions if presentation is playing.
-    public gotoDocument = action((index: number, from?: Doc, group?: boolean) => {
-        Doc.UnBrushAllDocs();
-        if (index >= 0 && index < this.childDocs.length) {
-            this.rootDoc._itemIndex = index;
-            const activeItem: Doc = this.activeItem;
-            const targetDoc: Doc = this.targetDoc;
-            if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) {
-                DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia);
-            }
-            if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) {
-                this.stopTempMedia(from.presentationTargetDoc);
-            }
-            // If next slide is audio / video 'Play automatically' then the next slide should be played
-            if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) {
-                this.startTempMedia(targetDoc, activeItem);
-            }
-            if (targetDoc) {
-                targetDoc && runInAction(() => {
-                    if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0;
-                    else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500;
-                });
-                setTimeout(() => targetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510);
-            }
-            if (targetDoc?.lastFrame !== undefined) {
-                targetDoc._currentFrame = 0;
-            }
-            if (!group) this._selectedArray.clear();
-            this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array
-            if (this.layoutDoc._viewType === "stacking" && !group) this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list
-            this.onHideDocument(); //Handles hide after/before
-        }
-    });
-
-    _navTimer!: NodeJS.Timeout;
-    navigateToView = (targetDoc: Doc, activeItem: Doc) => {
-        clearTimeout(this._navTimer);
-        const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
-        bestTarget && runInAction(() => {
-            if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) {
-                bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
-                bestTarget._scrollTop = activeItem.presPinViewScroll;
-            } else if (bestTarget.type === DocumentType.COMPARISON) {
-                bestTarget._clipWidth = activeItem.presPinClipWidth;
-            } else if (bestTarget.type === DocumentType.VID) {
-                bestTarget._currentTimecode = activeItem.presPinTimecode;
-            } else {
-                bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
-                bestTarget._panX = activeItem.presPinViewX;
-                bestTarget._panY = activeItem.presPinViewY;
-                bestTarget._viewScale = activeItem.presPinViewScale;
-            }
-            this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
-        });
-    }
-
-    /**
-     * This method makes sure that cursor navigates to the element that
-     * has the option open and last in the group. 
-     * Design choice: If the next document is not in presCollection or 
-     * presCollection itself then if there is a presCollection it will add
-     * a new tab. If presCollection is undefined it will open the document
-     * on the right. 
-     */
-    navigateToElement = async (curDoc: Doc) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const srcContext = Cast(targetDoc.context, Doc, null);
-        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-        const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
-        const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc);
-        const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === srcContext);
-        this.turnOffEdit();
-        // Handles the setting of presCollection
-        if (includesDoc) {
-            //Case 1: Pres collection should not change as it is already the same
-        } else if (tab !== undefined) {
-            // Case 2: Pres collection should update
-            this.layoutDoc.presCollection = srcContext;
-        }
-        const presStatus = this.rootDoc.presStatus;
-        const selViewCache = Array.from(this._selectedArray.keys());
-        const dragViewCache = Array.from(this._dragArray);
-        const eleViewCache = Array.from(this._eleArray);
-        const self = this;
-        const resetSelection = action(() => {
-            const presDocView = DocumentManager.Instance.getDocumentView(self.rootDoc);
-            if (presDocView) SelectionManager.SelectView(presDocView, false);
-            self.rootDoc.presStatus = presStatus;
-            self._selectedArray.clear();
-            selViewCache.forEach(doc => self._selectedArray.set(doc, undefined));
-            self._dragArray.splice(0, self._dragArray.length, ...dragViewCache);
-            self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
-        });
-        const openInTab = (doc: Doc, finished?: () => void) => {
-            collectionDocView ? collectionDocView.props.addDocTab(doc, "") : this.props.addDocTab(doc, ":left");
-            this.layoutDoc.presCollection = targetDoc;
-            // this still needs some fixing
-            setTimeout(resetSelection, 500);
-            if (doc !== targetDoc) {
-                setTimeout(finished ?? emptyFunction, 100); /// give it some time to create the targetDoc if we're opening up its context
-            } else {
-                finished?.();
-            }
-        };
-        // If openDocument is selected then it should open the document for the user
-        if (activeItem.openDocument) {
-            LightboxView.SetLightboxDoc(targetDoc);
-        } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) {
-            LightboxView.SetLightboxDoc(undefined);
-            await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right
-        } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
-            LightboxView.SetLightboxDoc(undefined);
-            //awaiting jump so that new scale can be found, since jumping is async     
-            await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right    
-        }
-        // After navigating to the document, if it is added as a presPinView then it will
-        // adjust the pan and scale to that of the pinView when it was added.
-        if (activeItem.presPinView) {
-            // if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target
-            this.navigateToView(targetDoc, activeItem);
-        }
-        // TODO: Add progressivize for navigating web (storing websites for given frames)
-
-    }
-
-    /**
-     * Uses the viewfinder to progressivize through the different views of a single collection.
-     * @param presTargetDoc: document for which internal zoom is used
-     */
-    zoomProgressivizeNext = (activeItem: Doc) => {
-        const targetDoc: Doc = this.targetDoc;
-        const srcContext = Cast(targetDoc?.context, Doc, null);
-        const docView = DocumentManager.Instance.getDocumentView(targetDoc);
-        const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
-        const vfWidth = this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
-        const vfTop = this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
-        const vfHeight = this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
-        // Case 1: document that is not a Golden Layout tab
-        if (srcContext) {
-            const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
-            if (srcDocView) {
-                const layoutdoc = Doc.Layout(targetDoc);
-                const panelWidth: number = srcDocView.props.PanelWidth();
-                const panelHeight: number = srcDocView.props.PanelHeight();
-                const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2;
-                const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2;
-                const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
-                srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
-                srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
-                srcContext._viewScale = newScale;
-            }
-        }
-        // Case 2: document is the containing collection
-        if (docView && !srcContext) {
-            const panelWidth: number = docView.props.PanelWidth();
-            const panelHeight: number = docView.props.PanelHeight();
-            const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
-            targetDoc._panX = vfLeft + (vfWidth / 2);
-            targetDoc._panY = vfTop + (vfWidth / 2);
-            targetDoc._viewScale = newScale;
-        }
-        const resize = document.getElementById('resizable');
-        if (resize) {
-            resize.style.width = vfWidth + 'px';
-            resize.style.height = vfHeight + 'px';
-            resize.style.top = vfTop + 'px';
-            resize.style.left = vfLeft + 'px';
-        }
-    }
-
-    /**
-     * For 'Hide Before' and 'Hide After' buttons making sure that
-     * they are hidden each time the presentation is updated.
-     */
-    @action
-    onHideDocument = () => {
-        this.childDocs.forEach((doc, index) => {
-            const curDoc = Cast(doc, Doc, null);
-            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (tagDoc) tagDoc.opacity = 1;
-            const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
-            const curInd: number = itemIndexes.indexOf(index);
-            if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1; }
-            else {
-                if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { }
-                else if (curDoc.presHideBefore) {
-                    if (index > this.itemIndex) {
-                        tagDoc.opacity = 0;
-                    } else if (!curDoc.presHideAfter) {
-                        tagDoc.opacity = 1;
-                    }
-                }
-                if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== (itemIndexes.length - 1)) { }
-                else if (curDoc.presHideAfter) {
-                    if (index < this.itemIndex) {
-                        tagDoc.opacity = 0;
-                    } else if (!curDoc.presHideBefore) {
-                        tagDoc.opacity = 1;
-                    }
-                }
-            }
-        });
-    }
-
-
-
-    //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
-    @action
-    startAutoPres = (startSlide: number) => {
-        this.updateCurrentPresentation();
-        let activeItem: Doc = this.activeItem;
-        let targetDoc: Doc = this.targetDoc;
-        let duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
-        const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
-        const load = async () => { // Wrap the loop into an async function for this to work
-            for (var i = startSlide; i < this.childDocs.length; i++) {
-                activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-                targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
-                duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
-                if (duration < 100) { duration = 2500; }
-                if (NumCast(targetDoc.lastFrame) > 0) {
-                    for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) {
-                        await timer(duration / NumCast(targetDoc.lastFrame));
-                        this.next();
-                    }
-                }
-
-                await timer(duration); this.next(); // then the created Promise can be awaited
-                if (i === this.childDocs.length - 1) {
-                    setTimeout(() => {
-                        clearTimeout(this._presTimer);
-                        if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = PresStatus.Manual;
-                        else if (this.layoutDoc.presLoop) this.startAutoPres(0);
-                    }, duration);
-                }
-            }
-        };
-        this.layoutDoc.presStatus = PresStatus.Autoplay;
-        this.startPresentation(startSlide);
-        this.gotoDocument(startSlide, activeItem);
-        load();
-    }
-
-    @action
-    pauseAutoPres = () => {
-        if (this.layoutDoc.presStatus === PresStatus.Autoplay) {
-            if (this._presTimer) clearTimeout(this._presTimer);
-            this.layoutDoc.presStatus = PresStatus.Manual;
-            this.layoutDoc.presLoop = false;
-            this.childDocs.forEach(this.stopTempMedia);
-        }
-    }
-
-    //The function that resets the presentation by removing every action done by it. It also
-    //stops the presentaton.
-    resetPresentation = () => {
-        this.rootDoc._itemIndex = 0;
-        this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => {
-            try {
-                doc.opacity = 1;
-            } catch (e) {
-                console.log("Reset presentation error: ", e);
-            }
-        });
-    }
-
-    @action togglePath = (srcContext: Doc, off?: boolean) => {
-        if (off) {
-            this._pathBoolean = false;
-            srcContext.presPathView = false;
-        } else {
-            runInAction(() => this._pathBoolean = !this._pathBoolean);
-            srcContext.presPathView = this._pathBoolean;
-        }
-    }
-
-    @action toggleExpandMode = () => {
-        runInAction(() => this._expandBoolean = !this._expandBoolean);
-        this.rootDoc.expandBoolean = this._expandBoolean;
-        this.childDocs.forEach((doc) => {
-            doc.presExpandInlineButton = this._expandBoolean;
-        });
-    }
-
-    /**
-     * The function that starts the presentation at the given index, also checking if actions should be applied
-     * directly at start.
-     * @param startIndex: index that the presentation will start at
-     */
-    startPresentation = (startIndex: number) => {
-        this.updateCurrentPresentation();
-        this.childDocs.map(doc => {
-            const tagDoc = doc.presentationTargetDoc as Doc;
-            if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) {
-                tagDoc.opacity = 0;
-            }
-            if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) {
-                tagDoc.opacity = 0;
-            }
-        });
-    }
-
-    /**
-     * The method called to open the presentation as a minimized view
-     */
-    @action
-    updateMinimize = () => {
-        const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc);
-        if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) {
-            console.log("case 1");
-            this.layoutDoc.presStatus = PresStatus.Edit;
-            Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc);
-            CollectionDockingView.AddSplit(this.rootDoc, "right");
-        } else if (this.layoutDoc.context && docView) {
-            console.log("case 2");
-            this.layoutDoc.presStatus = PresStatus.Edit;
-            clearTimeout(this._presTimer);
-            const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
-            this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250);
-            this.rootDoc.y = pt[1] + 10;
-            this.rootDoc._height = 35;
-            this.rootDoc._width = 250;
-            docView.props.removeDocument?.(this.layoutDoc);
-            Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc);
-        } else {
-            console.log("case 3");
-            // TODO glr: fix this case
-        }
-    }
-
-    /**
-     * Called when the user changes the view type
-     * Either 'List' (stacking) or 'Slides' (carousel)
-     */
-    // @undoBatch
-    viewChanged = action((e: React.ChangeEvent) => {
-        //@ts-ignore
-        const viewType = e.target.selectedOptions[0].value as CollectionViewType;
-        // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
-        viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined);
-        this.rootDoc._viewType = viewType;
-        if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 0;
-    });
-
-    /**
-     * Called when the user changes the view type
-     * Either 'List' (stacking) or 'Slides' (carousel)
-     */
-    // @undoBatch
-    mediaStopChanged = action((e: React.ChangeEvent) => {
-        const activeItem: Doc = this.activeItem;
-        //@ts-ignore
-        const stopDoc = e.target.selectedOptions[0].value as string;
-        const stopDocIndex: number = Number(stopDoc[0]);
-        activeItem.mediaStopDoc = stopDocIndex;
-        if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) {
-            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
-            list.push(activeItem);
-            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
-            console.log(list);
-        } else {
-            this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List<Doc>();
-            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
-            list.push(activeItem);
-            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
-            console.log(list);
-        }
-    });
-
-
-    setMovementName = action((movement: any, activeItem: Doc): string => {
-        let output: string = 'none';
-        switch (movement) {
-            case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom
-            case PresMovement.Pan: output = 'Pan'; break; //Pan
-            case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut
-            case PresMovement.None: output = 'None'; break; //None
-            default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom
-        }
-        return output;
-    });
-
-    whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isChildActive = isActive));
-    // For dragging documents into the presentation trail
-    addDocumentFilter = (docs: Doc[]) => {
-        docs.forEach((doc, i) => {
-            if (doc.presentationTargetDoc) return true;
-            if (doc.type === DocumentType.LABEL) {
-                const audio = Cast(doc.annotationOn, Doc, null);
-                if (audio) {
-                    audio.mediaStart = "manual";
-                    audio.mediaStop = "manual";
-                    audio.presStartTime = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */));
-                    audio.presEndTime = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */));
-                    audio.presDuration = audio.presStartTime - audio.presEndTime;
-                    TabDocView.PinDoc(audio, { audioRange: true });
-                    setTimeout(() => this.removeDocument(doc), 0);
-                    return false;
-                }
-            } else {
-                if (!doc.aliasOf) {
-                    const original = Doc.MakeAlias(doc);
-                    TabDocView.PinDoc(original);
-                    setTimeout(() => this.removeDocument(doc), 0);
-                    return false;
-                } else {
-                    if (!doc.presentationTargetDoc) doc.title = doc.title + " - Slide";
-                    doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
-                    doc.presMovement = PresMovement.Zoom;
-                    if (this._expandBoolean) doc.presExpandInlineButton = true;
-                }
-            }
-        });
-        return true;
-    }
-    childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
-    removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
-    getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
-    panelHeight = () => this.props.PanelHeight() - 40;
-    isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.SelectedTool === InkTool.None && this.props.layerProvider?.(this.layoutDoc) !== false) &&
-        (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
-
-    /**
-     * For sorting the array so that the order is maintained when it is dropped.
-     */
-    @action
-    sortArray = (): Doc[] => {
-        return this.childDocs.filter(doc => this._selectedArray.has(doc));
-    }
-
-    /**
-     * Method to get the list of selected items in the order in which they have been selected
-     */
-    @computed get listOfSelected() {
-        const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => {
-            const curDoc = Cast(doc, Doc, null);
-            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}.  {curDoc.title}</b></div>;
-            else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}.  {curDoc.title}</div>;
-            else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}.  {curDoc.title}</div>;
-        });
-        return list;
-    }
-
-    @action
-    selectPres = () => {
-        const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
-        presDocView && SelectionManager.SelectView(presDocView, false);
-    }
-
-    //Regular click
-    @action
-    selectElement = async (doc: Doc) => {
-        const context = Cast(doc.context, Doc, null);
-        this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem);
-        if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0);
-        else this.updateCurrentPresentation(context);
-
-        if (this.activeItem.setPosition &&
-            this.activeItem.y !== undefined &&
-            this.activeItem.x !== undefined &&
-            this.targetDoc.x !== undefined &&
-            this.targetDoc.y !== undefined) {
-            const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
-            const time = 10;
-            const ydiff = NumCast(this.activeItem.y) - NumCast(this.targetDoc.y);
-            const xdiff = NumCast(this.activeItem.x) - NumCast(this.targetDoc.x);
-
-            for (let i = 0; i < time; i++) {
-                this.targetDoc.x = NumCast(this.targetDoc.x) + xdiff / time;
-                this.targetDoc.y = NumCast(this.targetDoc.y) + ydiff / time;
-                await timer(0.1);
-            }
-        }
-    }
-
-    //Command click
-    @action
-    multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
-        if (!this._selectedArray.has(doc)) {
-            this._selectedArray.set(doc, undefined);
-            this._eleArray.push(ref);
-            this._dragArray.push(drag);
-        } else {
-            this._selectedArray.delete(doc);
-            this.removeFromArray(this._eleArray, doc);
-            this.removeFromArray(this._dragArray, doc);
-        }
-        this.selectPres();
-    }
-
-    removeFromArray = (arr: any[], val: any) => {
-        const index: number = arr.indexOf(val);
-        const ret: any[] = arr.splice(index, 1);
-        arr = ret;
-    }
-
-    //Shift click
-    @action
-    shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
-        this._selectedArray.clear();
-        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        if (this.activeItem) {
-            for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
-                this._selectedArray.set(this.childDocs[i], undefined);
-                this._eleArray.push(ref);
-                this._dragArray.push(drag);
-            }
-        }
-        this.selectPres();
-    }
-
-    //regular click
-    @action
-    regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean) => {
-        this._selectedArray.clear();
-        this._selectedArray.set(doc, undefined);
-        this._eleArray.splice(0, this._eleArray.length, ref);
-        this._dragArray.splice(0, this._dragArray.length, drag);
-        focus && this.selectElement(doc);
-        this.selectPres();
-    }
-
-    modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => {
-        if (cmdClick) this.multiSelect(doc, ref, drag);
-        else if (shiftClick) this.shiftSelect(doc, ref, drag);
-        else this.regularSelect(doc, ref, drag, focus);
-    }
-
-    static keyEventsWrapper = (e: KeyboardEvent) => {
-        PresBox.Instance.keyEvents(e);
-    }
-
-    // Key for when the presentaiton is active
-    @action
-    keyEvents = (e: KeyboardEvent) => {
-        if (e.target instanceof HTMLInputElement) return;
-        let handled = false;
-        const anchorNode = document.activeElement as HTMLDivElement;
-        if (anchorNode && anchorNode.className?.includes("lm_title")) return;
-        switch (e.key) {
-            case "Backspace":
-                if (this.layoutDoc.presStatus === "edit") {
-                    undoBatch(action(() => {
-                        for (const doc of Array.from(this._selectedArray.keys())) {
-                            this.removeDocument(doc);
-                        }
-                        this._selectedArray.clear();
-                        this._eleArray.length = 0;
-                        this._dragArray.length = 0;
-                    }))();
-                    handled = true;
-                }
-                break;
-            case "Escape":
-                if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.updateMinimize(); }
-                else if (this.layoutDoc.presStatus === "edit") { this._selectedArray.clear(); this._eleArray.length = this._dragArray.length = 0; }
-                else this.layoutDoc.presStatus = "edit";
-                if (this._presTimer) clearTimeout(this._presTimer);
-                handled = true;
-                break;
-            case "Down": case "ArrowDown":
-            case "Right": case "ArrowRight":
-                if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { // TODO: update to work properly
-                    this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1;
-                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
-                } else {
-                    this.next();
-                    if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
-                }
-                handled = true;
-                break;
-            case "Up": case "ArrowUp":
-            case "Left": case "ArrowLeft":
-                if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly
-                    this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1;
-                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
-                } else {
-                    this.back();
-                    if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
-                }
-                handled = true;
-                break;
-            case "Spacebar": case " ":
-                if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex);
-                else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer);
-                handled = true;
-                break;
-            case "a":
-                if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === "edit") {
-                    this._selectedArray.clear();
-                    this.childDocs.forEach(doc => this._selectedArray.set(doc, undefined));
-                    handled = true;
-                }
-            default:
-                break;
-        }
-        if (handled) {
-            e.stopPropagation();
-            e.preventDefault();
-        }
-    }
-
-    /**
-     * 
-     */
-    @action
-    viewPaths = () => {
-        const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
-        if (srcContext) {
-            this.togglePath(srcContext);
-        }
-    }
-
-    getAllIndexes = (arr: Doc[], val: Doc): number[] => {
-        const indexes = [];
-        for (let i = 0; i < arr.length; i++) {
-            arr[i] === val && indexes.push(i);
-        }
-        return indexes;
-    }
-
-    // Adds the index in the pres path graphically
-    @computed get order() {
-        const order: JSX.Element[] = [];
-        const docs: Doc[] = [];
-        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
-        const dv = DocumentManager.Instance.getDocumentView(presCollection);
-        this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            const srcContext = Cast(tagDoc.context, Doc, null);
-            const width = NumCast(tagDoc._width) / 10;
-            const height = Math.max(NumCast(tagDoc._height) / 10, 15);
-            const edge = Math.max(width, height);
-            const fontSize = edge * 0.8;
-            const gap = 2;
-            if (presCollection === srcContext) {
-                // Case A: Document is contained within the collection
-                if (docs.includes(tagDoc)) {
-                    const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length;
-                    docs.push(tagDoc);
-                    order.push(
-                        <div className="pathOrder"
-                            key={tagDoc.id + 'pres' + index}
-                            style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - (edge / 2)), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
-                            onClick={() => this.selectElement(doc)}>
-                            <div className="pathOrder-frame">{index + 1}</div>
-                        </div>);
-                } else {
-                    docs.push(tagDoc);
-                    order.push(
-                        <div className="pathOrder"
-                            key={tagDoc.id + 'pres' + index}
-                            style={{ top: NumCast(tagDoc.y) - (edge / 2), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
-                            onClick={() => this.selectElement(doc)}>
-                            <div className="pathOrder-frame">{index + 1}</div>
-                        </div>);
-                }
-            } else if (doc.presPinView && presCollection === tagDoc && dv) {
-                // Case B: Document is presPinView and is presCollection
-                const scale: number = 1 / NumCast(doc.presPinViewScale);
-                const height: number = dv.props.PanelHeight() * scale;
-                const width: number = dv.props.PanelWidth() * scale;
-                const indWidth = width / 10;
-                const indHeight = Math.max(height / 10, 15);
-                const indEdge = Math.max(indWidth, indHeight);
-                const indFontSize = indEdge * 0.8;
-                const xLoc: number = NumCast(doc.presPinViewX) - (width / 2);
-                const yLoc: number = NumCast(doc.presPinViewY) - (height / 2);
-                docs.push(tagDoc);
-                order.push(
-                    <>
-                        <div className="pathOrder"
-                            key={tagDoc.id + 'pres' + index}
-                            style={{ top: yLoc - (indEdge / 2), left: xLoc - (indEdge / 2), width: indEdge, height: indEdge, fontSize: indFontSize }}
-                            onClick={() => this.selectElement(doc)}
-                        >
-                            <div className="pathOrder-frame">{index + 1}</div>
-                        </div>
-                        <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div>
-                    </>);
-            }
-        });
-        return order;
-    }
-
-    /**
-     * Method called for viewing paths which adds a single line with
-     * points at the center of each document added.
-     * Design choice: When this is called it sets _fitToBox as true so the
-     * user can have an overview of all of the documents in the collection.
-     * (Design needed for when documents in presentation trail are in another
-     * collection)
-     */
-    @computed get paths() {
-        let pathPoints = "";
-        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
-        this.childDocs.forEach((doc, index) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            const srcContext = Cast(tagDoc?.context, Doc, null);
-            if (tagDoc && presCollection === srcContext) {
-                const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2);
-                const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2);
-                if (index = 0) pathPoints = n1x + "," + n1y;
-                else pathPoints = pathPoints + " " + n1x + "," + n1y;
-            } else if (doc.presPinView && presCollection === tagDoc) {
-                const n1x = NumCast(doc.presPinViewX);
-                const n1y = NumCast(doc.presPinViewY);
-                if (index = 0) pathPoints = n1x + "," + n1y;
-                else pathPoints = pathPoints + " " + n1x + "," + n1y;
-            }
-        });
-        return (<polyline
-            points={pathPoints}
-            style={{
-                opacity: 1,
-                stroke: "#69a6db",
-                strokeWidth: 5,
-                strokeDasharray: '10 5',
-                boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
-            }}
-            fill="none"
-            markerStart="url(#markerArrow)"
-            markerMid="url(#markerSquare)"
-            markerEnd="url(#markerSquareFilled)"
-        />);
-    }
-
-    // Converts seconds to ms and updates presTransition
-    setTransitionTime = (number: String, change?: number) => {
-        let timeInMS = Number(number) * 1000;
-        if (change) timeInMS += change;
-        if (timeInMS < 100) timeInMS = 100;
-        if (timeInMS > 10000) timeInMS = 10000;
-        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS);
-    }
-
-    // Converts seconds to ms and updates presDuration
-    setDurationTime = (number: String, change?: number) => {
-        let timeInMS = Number(number) * 1000;
-        if (change) timeInMS += change;
-        if (timeInMS < 100) timeInMS = 100;
-        if (timeInMS > 20000) timeInMS = 20000;
-        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS);
-    }
-
-    /**
-     * When the movement dropdown is changes
-     */
-    @undoBatch
-    updateMovement = action((movement: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach((doc) => {
-            switch (movement) {
-                case PresMovement.Zoom: //Pan and zoom
-                    doc.presMovement = PresMovement.Zoom;
-                    break;
-                case PresMovement.Pan: //Pan
-                    doc.presMovement = PresMovement.Pan;
-                    break;
-                case PresMovement.Jump: //Jump Cut
-                    doc.presJump = true;
-                    doc.presMovement = PresMovement.Jump;
-                    break;
-                case PresMovement.None: default:
-                    doc.presMovement = PresMovement.None;
-                    break;
-            }
-        });
-    });
-
-    @undoBatch
-    @action
-    updateHideBefore = (activeItem: Doc) => {
-        activeItem.presHideBefore = !activeItem.presHideBefore;
-        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore);
-    }
-
-    @undoBatch
-    @action
-    updateHideAfter = (activeItem: Doc) => {
-        activeItem.presHideAfter = !activeItem.presHideAfter;
-        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter);
-    }
-
-    @undoBatch
-    @action
-    updateOpenDoc = (activeItem: Doc) => {
-        activeItem.openDocument = !activeItem.openDocument;
-        Array.from(this._selectedArray.keys()).forEach((doc) => {
-            doc.openDocument = activeItem.openDocument;
-        });
-    }
-
-    @undoBatch
-    @action
-    updateEffectDirection = (effect: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach((doc) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            switch (effect) {
-                case PresEffect.Left:
-                    tagDoc.presEffectDirection = PresEffect.Left;
-                    break;
-                case PresEffect.Right:
-                    tagDoc.presEffectDirection = PresEffect.Right;
-                    break;
-                case PresEffect.Top:
-                    tagDoc.presEffectDirection = PresEffect.Top;
-                    break;
-                case PresEffect.Bottom:
-                    tagDoc.presEffectDirection = PresEffect.Bottom;
-                    break;
-                case PresEffect.Center: default:
-                    tagDoc.presEffectDirection = PresEffect.Center;
-                    break;
-            }
-        });
-    }
-
-    @undoBatch
-    @action
-    updateEffect = (effect: any, all?: boolean) => {
-        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
-        array.forEach((doc) => {
-            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            switch (effect) {
-                case PresEffect.Bounce:
-                    tagDoc.presEffect = PresEffect.Bounce;
-                    break;
-                case PresEffect.Fade:
-                    tagDoc.presEffect = PresEffect.Fade;
-                    break;
-                case PresEffect.Flip:
-                    tagDoc.presEffect = PresEffect.Flip;
-                    break;
-                case PresEffect.Roll:
-                    tagDoc.presEffect = PresEffect.Roll;
-                    break;
-                case PresEffect.Rotate:
-                    tagDoc.presEffect = PresEffect.Rotate;
-                    break;
-                case PresEffect.None: default:
-                    tagDoc.presEffect = PresEffect.None;
-                    break;
-            }
-        });
-    }
-
-    _batch: UndoManager.Batch | undefined = undefined;
-
-    @computed get transitionDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const type = targetDoc.type;
-        const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection);
-        const isPinWithView: boolean = BoolCast(activeItem.presPinView);
-        if (activeItem && targetDoc) {
-            const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
-            let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
-            if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
-            const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
-            activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
-            return (
-                <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
-                    <div className="ribbon-box">
-                        Movement
-                        {isPresCollection || (isPresCollection && isPinWithView) ?
-                            <div className="ribbon-property" style={{ marginLeft: 0, height: 25, textAlign: 'left', paddingLeft: 5, paddingRight: 5, fontSize: 10 }}>
-                                {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"}
-                            </div>
-                            :
-                            <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}>
-                                {this.setMovementName(activeItem.presMovement, activeItem)}
-                                <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openMovementDropdown ? PresColor.DarkBlue : 'black' }} icon={"angle-down"} />
-                                <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}>
-                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None</div>
-                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom</div>
-                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan</div>
-                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut</div>
-                                </div>
-                            </div>
-                        }
-                        <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}>
-                            <div className="presBox-subheading">Movement Speed</div>
-                            <div className="ribbon-property">
-                                <input className="presBox-input"
-                                    type="number" value={transitionSpeed}
-                                    onChange={action((e) => this.setTransitionTime(e.target.value))} /> s
-                            </div>
-                            <div className="ribbon-propertyUpDown">
-                                <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), 1000))}>
-                                    <FontAwesomeIcon icon={"caret-up"} />
-                                </div>
-                                <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), -1000))}>
-                                    <FontAwesomeIcon icon={"caret-down"} />
-                                </div>
-                            </div>
-                        </div>
-                        <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed}
-                            className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}
-                            id="toolbar-slider"
-                            onPointerDown={() => this._batch = UndoManager.StartBatch("presTransition")}
-                            onPointerUp={() => this._batch?.end()}
-                            onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                                e.stopPropagation();
-                                this.setTransitionTime(e.target.value);
-                            }} />
-                        <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
-                            <div className="slider-text">Fast</div>
-                            <div className="slider-text">Medium</div>
-                            <div className="slider-text">Slow</div>
-                        </div>
-                    </div>
-                    <div className="ribbon-box">
-                        Visibility {"&"} Duration
-                        <div className="ribbon-doubleButton">
-                            {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide before presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideBefore ? "active" : ""}`} onClick={() => this.updateHideBefore(activeItem)}>Hide before</div></Tooltip>}
-                            {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide after presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideAfter ? "active" : ""}`} onClick={() => this.updateHideAfter(activeItem)}>Hide after</div></Tooltip>}
-                            <Tooltip title={<><div className="dash-tooltip">{"Open in lightbox view"}</div></>}><div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? PresColor.LightBlue : "" }} onClick={() => this.updateOpenDoc(activeItem)}>Lightbox</div></Tooltip>
-                        </div>
-                        {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <>
-                            <div className="ribbon-doubleButton" >
-                                <div className="presBox-subheading">Slide Duration</div>
-                                <div className="ribbon-property">
-                                    <input className="presBox-input"
-                                        type="number" value={duration}
-                                        onChange={action((e) => this.setDurationTime(e.target.value))} /> s
-                            </div>
-                                <div className="ribbon-propertyUpDown">
-                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}>
-                                        <FontAwesomeIcon icon={"caret-up"} />
-                                    </div>
-                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}>
-                                        <FontAwesomeIcon icon={"caret-down"} />
-                                    </div>
-                                </div>
-                            </div>
-                            <input type="range" step="0.1" min="0.1" max="20" value={duration}
-                                style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }}
-                                className={"toolbar-slider"} id="duration-slider"
-                                onPointerDown={() => { this._batch = UndoManager.StartBatch("presDuration"); }}
-                                onPointerUp={() => { if (this._batch) this._batch.end(); }}
-                                onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }}
-                            />
-                            <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}>
-                                <div className="slider-text">Short</div>
-                                <div className="slider-text">Medium</div>
-                                <div className="slider-text">Long</div>
-                            </div>
-                        </>}
-                    </div>
-                    {isPresCollection ? (null) : <div className="ribbon-box">
-                        Effects
-                        <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${PresColor.DarkBlue}` : 'solid 1px black' }}>
-                            {effect}
-                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? PresColor.DarkBlue : 'black' }} icon={"angle-down"} />
-                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.None || !targetDoc.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div>
-                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div>
-                            </div>
-                        </div>
-                        <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}>
-                            <div className="presBox-subheading" >Effect direction</div>
-                            <div className="ribbon-property">
-                                {this.effectDirection}
-                            </div>
-                        </div>
-                        <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Left ? PresColor.LightBlue : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Right ? PresColor.LightBlue : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Top ? PresColor.LightBlue : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Bottom ? PresColor.LightBlue : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
-                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection === PresEffect.Center || !targetDoc.presEffectDirection ? `solid 2px ${PresColor.LightBlue}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip>
-                        </div>
-                    </div>}
-                    <div className="ribbon-final-box">
-                        <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
-                            Apply to all
-                        </div>
-                    </div>
-                </div >
-            );
-        }
-    }
-
-    @computed get effectDirection(): string {
-        let effect = '';
-        switch (this.targetDoc.presEffectDirection) {
-            case 'left': effect = "Enter from left"; break;
-            case 'right': effect = "Enter from right"; break;
-            case 'top': effect = "Enter from top"; break;
-            case 'bottom': effect = "Enter from bottom"; break;
-            default: effect = "Enter from center"; break;
-        }
-        return effect;
-    }
-
-    @undoBatch
-    @action
-    applyTo = (array: Doc[]) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        this.updateMovement(activeItem.presMovement, true);
-        this.updateEffect(targetDoc.presEffect, true);
-        this.updateEffectDirection(targetDoc.presEffectDirection, true);
-        array.forEach((doc) => {
-            const curDoc = Cast(doc, Doc, null);
-            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
-            if (tagDoc && targetDoc) {
-                curDoc.presTransition = activeItem.presTransition;
-                curDoc.presDuration = activeItem.presDuration;
-                curDoc.presHideBefore = activeItem.presHideBefore;
-                curDoc.presHideAfter = activeItem.presHideAfter;
-            }
-        });
-    }
-
-    @computed get presPinViewOptionsDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 16, filter: 'invert(1)' }} />;
-        return (
-            <>
-                {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)}
-                <div className="ribbon-doubleButton">
-                    <Tooltip title={<><div className="dash-tooltip">{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}</div></>}><div className="ribbon-toggle" style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? PresColor.LightBlue : "" }}
-                        onClick={() => {
-                            activeItem.presPinView = !activeItem.presPinView;
-                            targetDoc.presPinView = activeItem.presPinView;
-                            if (activeItem.presPinView) {
-                                if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
-                                    const scroll = targetDoc._scrollTop;
-                                    activeItem.presPinView = true;
-                                    activeItem.presPinViewScroll = scroll;
-                                } else if (targetDoc.type === DocumentType.VID) {
-                                    activeItem.presPinTimecode = targetDoc._currentTimecode;
-                                } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
-                                    const x = targetDoc._panX;
-                                    const y = targetDoc._panY;
-                                    const scale = targetDoc._viewScale;
-                                    activeItem.presPinView = true;
-                                    activeItem.presPinViewX = x;
-                                    activeItem.presPinViewY = y;
-                                    activeItem.presPinViewScale = scale;
-                                } else if (targetDoc.type === DocumentType.COMPARISON) {
-                                    const width = targetDoc._clipWidth;
-                                    activeItem.presPinClipWidth = width;
-                                    activeItem.presPinView = true;
-                                }
-                            }
-                        }}>{presPinWithViewIcon}</div></Tooltip>
-                    {activeItem.presPinView ? <Tooltip title={<><div className="dash-tooltip">{"Update the pinned view with the view of the selected document"}</div></>}><div className="ribbon-button"
-                        onClick={() => {
-                            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
-                                const scroll = targetDoc._scrollTop;
-                                activeItem.presPinViewScroll = scroll;
-                            } else if (targetDoc.type === DocumentType.VID) {
-                                activeItem.presPinTimecode = targetDoc._currentTimecode;
-                            } else if (targetDoc.type === DocumentType.COMPARISON) {
-                                const clipWidth = targetDoc._clipWidth;
-                                activeItem.presPinClipWidth = clipWidth;
-                            } else {
-                                const x = targetDoc._panX;
-                                const y = targetDoc._panY;
-                                const scale = targetDoc._viewScale;
-                                activeItem.presPinViewX = x;
-                                activeItem.presPinViewY = y;
-                                activeItem.presPinViewScale = scale;
-                            }
-                        }}>Update</div></Tooltip> : (null)}
-                </div>
-            </>
-        );
-    }
-
-    @computed get panOptionsDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        return (
-            <>
-                {this.panable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
-                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
-                        <div className="presBox-subheading">Pan X</div>
-                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
-                            <input className="presBox-input"
-                                style={{ textAlign: 'left', width: 50 }}
-                                type="number" value={NumCast(activeItem.presPinViewX)}
-                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} />
-                        </div>
-                    </div>
-                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
-                        <div className="presBox-subheading">Pan Y</div>
-                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
-                            <input className="presBox-input"
-                                style={{ textAlign: 'left', width: 50 }}
-                                type="number" value={NumCast(activeItem.presPinViewY)}
-                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} />
-                        </div>
-                    </div>
-                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
-                        <div className="presBox-subheading">Scale</div>
-                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
-                            <input className="presBox-input"
-                                style={{ textAlign: 'left', width: 50 }}
-                                type="number" value={NumCast(activeItem.presPinViewScale)}
-                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} />
-                        </div>
-                    </div>
-                </div> : (null)}
-            </>
-        );
-    }
-
-    @computed get scrollOptionsDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        return (
-            <>
-                {this.scrollable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
-                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
-                        <div className="presBox-subheading">Scroll</div>
-                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
-                            <input className="presBox-input"
-                                style={{ textAlign: 'left', width: 50 }}
-                                type="number" value={NumCast(activeItem.presPinViewScroll)}
-                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} />
-                        </div>
-                    </div>
-                </div> : (null)}
-            </>
-        );
-    }
-
-    @computed get mediaStopSlides() {
-        const activeItem: Doc = this.activeItem;
-        const list = this.childDocs.map((doc, i) => {
-            if (i > this.itemIndex) {
-                return (
-                    <option>{i + 1}. {doc.title}</option>
-                );
-            }
-        });
-        return (
-            list
-        );
-    }
-
-    @computed get mediaOptionsDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const duration = Math.round(NumCast(activeItem[`${Doc.LayoutFieldKey(activeItem)}-duration`]) * 10);
-        const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc);
-        const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + ". " + this.childDocs[mediaStopDocInd - 1].title : "";
-        if (activeItem && targetDoc) {
-            return (
-                <div>
-                    <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                        <div>
-                            <div className="ribbon-box">
-                                Start {"&"} End Time
-                                <div className={"slider-headers"}>
-                                    <div className="slider-block" >
-                                        <div className="slider-text" style={{ fontWeight: 500 }}>
-                                            Start time (s)
-                                        </div>
-                                        <div id={"startTime"} className="slider-number" style={{ backgroundColor: PresColor.LightBackground }}>
-                                            <input className="presBox-input"
-                                                style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
-                                                type="number" value={NumCast(activeItem.presStartTime)}
-                                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presStartTime = Number(e.target.value); })}
-                                            />
-                                        </div>
-                                    </div>
-                                    <div className="slider-block">
-                                        <div className="slider-text" style={{ fontWeight: 500 }}>
-                                            Duration (s)
-                                        </div>
-                                        <div className="slider-number" style={{ backgroundColor: PresColor.LightBlue }}>
-                                            {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10}
-                                        </div>
-                                    </div>
-                                    <div className="slider-block">
-                                        <div className="slider-text" style={{ fontWeight: 500 }}>
-                                            End time (s)
-                                        </div>
-                                        <div id={"endTime"} className="slider-number" style={{ backgroundColor: PresColor.LightBackground }}>
-                                            <input className="presBox-input"
-                                                style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
-                                                type="number" value={NumCast(activeItem.presEndTime)}
-                                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presEndTime = Number(e.target.value); })}
-                                            />
-                                        </div>
-                                    </div>
-                                </div>
-                                <div className="multiThumb-slider">
-                                    <input type="range" step="0.1" min="0" max={duration / 10} value={NumCast(activeItem.presEndTime)}
-                                        style={{ gridColumn: 1, gridRow: 1 }}
-                                        className={`toolbar-slider ${"end"}`}
-                                        id="toolbar-slider"
-                                        onPointerDown={() => {
-                                            this._batch = UndoManager.StartBatch("presEndTime");
-                                            const endBlock = document.getElementById("endTime");
-                                            if (endBlock) {
-                                                endBlock.style.color = PresColor.LightBackground;
-                                                endBlock.style.backgroundColor = PresColor.DarkBlue;
-                                            }
-                                        }}
-                                        onPointerUp={() => {
-                                            this._batch?.end();
-                                            const endBlock = document.getElementById("endTime");
-                                            if (endBlock) {
-                                                endBlock.style.color = "black";
-                                                endBlock.style.backgroundColor = PresColor.LightBackground;
-                                            }
-                                        }}
-                                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                                            e.stopPropagation();
-                                            activeItem.presEndTime = Number(e.target.value);
-                                        }} />
-                                    <input type="range" step="0.1" min="0" max={duration / 10} value={NumCast(activeItem.presStartTime)}
-                                        style={{ gridColumn: 1, gridRow: 1 }}
-                                        className={`toolbar-slider ${"start"}`}
-                                        id="toolbar-slider"
-                                        onPointerDown={() => {
-                                            this._batch = UndoManager.StartBatch("presStartTime");
-                                            const startBlock = document.getElementById("startTime");
-                                            if (startBlock) {
-                                                startBlock.style.color = PresColor.LightBackground;
-                                                startBlock.style.backgroundColor = PresColor.DarkBlue;
-                                            }
-                                        }}
-                                        onPointerUp={() => {
-                                            this._batch?.end();
-                                            const startBlock = document.getElementById("startTime");
-                                            if (startBlock) {
-                                                startBlock.style.color = "black";
-                                                startBlock.style.backgroundColor = PresColor.LightBackground;
-                                            }
-                                        }}
-                                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
-                                            e.stopPropagation();
-                                            activeItem.presStartTime = Number(e.target.value);
-                                        }} />
-                                </div>
-                                <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
-                                    <div className="slider-text">0 s</div>
-                                    <div className="slider-text"></div>
-                                    <div className="slider-text">{duration / 10} s</div>
-                                </div>
-                            </div>
-                            <div className="ribbon-final-box">
-                                Playback
-                                <div className="presBox-subheading">Start playing:</div>
-                                <div className="presBox-radioButtons">
-                                    <div className="checkbox-container">
-                                        <input className="presBox-checkbox"
-                                            type="checkbox"
-                                            onChange={() => activeItem.mediaStart = "manual"}
-                                            checked={activeItem.mediaStart === "manual"}
-                                        />
-                                        <div>On click</div>
-                                    </div>
-                                    <div className="checkbox-container">
-                                        <input className="presBox-checkbox"
-                                            type="checkbox"
-                                            onChange={() => activeItem.mediaStart = "auto"}
-                                            checked={activeItem.mediaStart === "auto"}
-                                        />
-                                        <div>Automatically</div>
-                                    </div>
-                                </div>
-                                <div className="presBox-subheading">Stop playing:</div>
-                                <div className="presBox-radioButtons">
-                                    <div className="checkbox-container">
-                                        <input className="presBox-checkbox"
-                                            type="checkbox"
-                                            onChange={() => activeItem.mediaStop = "manual"}
-                                            checked={activeItem.mediaStop === "manual"}
-                                        />
-                                        <div>At audio end time</div>
-                                    </div>
-                                    <div className="checkbox-container">
-                                        <input className="presBox-checkbox"
-                                            type="checkbox"
-                                            onChange={() => activeItem.mediaStop = "auto"}
-                                            checked={activeItem.mediaStop === "auto"}
-                                        />
-                                        <div>On slide change</div>
-                                    </div>
-                                    {/* <div className="checkbox-container">
-                                    <input className="presBox-checkbox"
-                                        type="checkbox"
-                                        onChange={() => activeItem.mediaStop = "afterSlide"}
-                                        checked={activeItem.mediaStop === "afterSlide"}
-                                    />
-                                    <div className="checkbox-dropdown">
-                                        After chosen slide
-                                        <select className="presBox-viewPicker"
-                                            style={{ opacity: activeItem.mediaStop === "afterSlide" && this.itemIndex !== this.childDocs.length - 1 ? 1 : 0.3 }}
-                                            onPointerDown={e => e.stopPropagation()}
-                                            onChange={this.mediaStopChanged}
-                                            value={mediaStopDocStr}>
-                                            {this.mediaStopSlides}
-                                        </select>
-                                    </div>
-                                </div> */}
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div >
-            );
-        }
-    }
-
-    @computed get newDocumentToolbarDropdown() {
-        return (
-            <div>
-                <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                    <div className="layout-container" style={{ height: 'max-content' }}>
-                        <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
-                        <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
-                            <div className="title">Title</div>
-                            <div className="subtitle">Subtitle</div>
-                        </div>
-                        <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
-                            <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
-                        </div>
-                        <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
-                            <div className="title" style={{ alignSelf: 'center' }}>Title</div>
-                            <div className="content">Text goes here</div>
-                        </div>
-                    </div>
-                </div>
-            </div >
-        );
-    }
-
-    @observable openLayouts: boolean = false;
-    @observable addFreeform: boolean = true;
-    @observable layout: string = "";
-    @observable title: string = "";
-
-    @computed get newDocumentDropdown() {
-        return (
-            <div>
-                <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                    <div className="ribbon-box">
-                        Slide Title: <br></br>
-                        <input className="ribbon-textInput" placeholder="..." type="text" name="fname"
-                            onChange={(e) => {
-                                e.stopPropagation();
-                                e.preventDefault();
-                                runInAction(() => this.title = e.target.value);
-                            }}>
-                        </input>
-                    </div>
-                    <div className="ribbon-box">
-                        Choose type:
-                        <div className="ribbon-doubleButton">
-                            <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? "" : PresColor.LightBlue }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Text</div>
-                            <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? PresColor.LightBlue : "" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Freeform</div>
-                        </div>
-                    </div>
-                    <div className="ribbon-box" style={{ display: this.addFreeform ? "grid" : "none" }}>
-                        Preset layouts:
-                        <div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
-                            <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => this.layout = 'blank')} />
-                            <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => this.layout = 'title')}>
-                                <div className="title">Title</div>
-                                <div className="subtitle">Subtitle</div>
-                            </div>
-                            <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => this.layout = 'header')}>
-                                <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
-                            </div>
-                            <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => this.layout = 'content')}>
-                                <div className="title" style={{ alignSelf: 'center' }}>Title</div>
-                                <div className="content">Text goes here</div>
-                            </div>
-                            <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${PresColor.DarkBlue}` : '' }} onClick={action(() => this.layout = 'twoColumns')}>
-                                <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
-                                <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
-                                <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
-                            </div>
-                        </div>
-                        <div className="open-layout" onClick={action(() => this.openLayouts = !this.openLayouts)}>
-                            <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} />
-                        </div>
-                    </div>
-                    <div className="ribbon-final-box">
-                        <div className={this.title !== "" && (this.addFreeform && this.layout !== "" || !this.addFreeform) ? "ribbon-final-button-hidden" : "ribbon-final-button"} onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}>
-                            Create New Slide
-                        </div>
-                    </div>
-                </div>
-            </div >
-        );
-    }
-
-    createNewSlide = (layout?: string, title?: string, freeform?: boolean) => {
-        let doc = undefined;
-        if (layout) doc = this.createTemplate(layout);
-        if (freeform && layout) doc = this.createTemplate(layout, title);
-        if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
-        if (doc) {
-            const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
-            const data = Cast(presCollection?.data, listSpec(Doc));
-            const presData = Cast(this.rootDoc.data, listSpec(Doc));
-            if (data && presData) {
-                data.push(doc);
-                TabDocView.PinDoc(doc);
-                this.gotoDocument(this.childDocs.length, this.activeItem);
-            } else {
-                this.props.addDocTab(doc, "add:right");
-            }
-        }
-    }
-
-    createTemplate = (layout: string, input?: string) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        let x = 0;
-        let y = 0;
-        if (activeItem && targetDoc) {
-            x = NumCast(targetDoc.x);
-            y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20;
-        }
-        let doc = undefined;
-        const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", });
-        const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" });
-        const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" });
-        const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" });
-        const content = Docs.Create.TextDocument("Click to change text", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
-        const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" });
-        const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
-        switch (layout) {
-            case 'blank':
-                doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y });
-                break;
-            case 'title':
-                doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
-                break;
-            case 'header':
-                doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
-                break;
-            case 'content':
-                doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
-                break;
-            case 'twoColumns':
-                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
-                break;
-            default:
-                break;
-        }
-        return doc;
-    }
-
-    // Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
-    @computed get presentDropdown() {
-        return (
-            <div className={`dropdown-play ${this.presentTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.updateMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
-                    Mini-player
-                </div>
-                <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
-                    Sidebar player
-                </div>
-            </div>
-        );
-    }
-
-    // Case in which the document has keyframes to navigate to next key frame
-    @action
-    nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => {
-        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
-        const currentFrame = Cast(tagDoc._currentFrame, "number", null);
-        if (currentFrame === undefined) {
-            tagDoc._currentFrame = 0;
-            // CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
-            // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
-        }
-        // if (tagDoc.editScrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
-        CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc);
-        tagDoc._currentFrame = Math.max(0, (currentFrame || 0) + 1);
-        tagDoc.lastFrame = Math.max(NumCast(tagDoc._currentFrame), NumCast(tagDoc.lastFrame));
-    }
-
-    @action
-    prevKeyframe = (tagDoc: Doc, actItem: Doc): void => {
-        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
-        const currentFrame = Cast(tagDoc._currentFrame, "number", null);
-        if (currentFrame === undefined) {
-            tagDoc._currentFrame = 0;
-            // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
-        }
-        CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
-        tagDoc._currentFrame = Math.max(0, (currentFrame || 0) - 1);
-    }
-
-    /**
-     * Returns the collection type as a string for headers
-     */
-    @computed get stringType(): string {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        let type: string = '';
-        if (activeItem) {
-            switch (targetDoc.type) {
-                case DocumentType.PDF: type = "PDF"; break;
-                case DocumentType.RTF: type = "Text node"; break;
-                case DocumentType.COL: type = "Collection"; break;
-                case DocumentType.AUDIO: type = "Audio"; break;
-                case DocumentType.VID: type = "Video"; break;
-                case DocumentType.IMG: type = "Image"; break;
-                case DocumentType.WEB: type = "Web page"; break;
-                default: type = "Other node"; break;
-            }
-        }
-        return type;
-    }
-
-    @observable private openActiveColorPicker: boolean = false;
-    @observable private openViewedColorPicker: boolean = false;
-
-
-
-    @computed get progressivizeDropdown() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        if (activeItem && targetDoc) {
-            const activeFontColor = targetDoc["pres-text-color"] ? StrCast(targetDoc["pres-text-color"]) : "Black";
-            const viewedFontColor = targetDoc["pres-text-viewed-color"] ? StrCast(targetDoc["pres-text-viewed-color"]) : "Black";
-            return (
-                <div>
-                    <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
-                        <div className="ribbon-box">
-                            {this.stringType} selected
-                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
-                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? PresColor.LightBlue : "" }} onClick={this.progressivizeChild}>Contents</div>
-                                <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? PresColor.LightBlue : "" }} onClick={this.editProgressivize}>Edit</div>
-                            </div>
-                            <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
-                                <div className="presBox-subheading">Active text color</div>
-                                <div className="ribbon-colorBox" style={{ backgroundColor: activeFontColor, height: 15, width: 15 }} onClick={action(() => { this.openActiveColorPicker = !this.openActiveColorPicker; })}>
-                                </div>
-                            </div>
-                            {this.activeColorPicker}
-                            <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
-                                <div className="presBox-subheading">Viewed font color</div>
-                                <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => this.openViewedColorPicker = !this.openViewedColorPicker)}>
-                                </div>
-                            </div>
-                            {this.viewedColorPicker}
-                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
-                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? PresColor.LightBlue : "" }} onClick={this.progressivizeZoom}>Zoom</div>
-                                <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? PresColor.LightBlue : "" }} onClick={this.editZoomProgressivize}>Edit</div>
-                            </div>
-                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
-                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? PresColor.LightBlue : "" }} onClick={this.progressivizeScroll}>Scroll</div>
-                                <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? PresColor.LightBlue : "" }} onClick={this.editScrollProgressivize}>Edit</div>
-                            </div>
-                        </div>
-                        <div className="ribbon-final-box">
-                            Frames
-                            <div className="ribbon-doubleButton">
-                                <div className="ribbon-frameSelector">
-                                    <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc, activeItem); }}>
-                                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
-                                    </div>
-                                    <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.keyFrameEditing ? "white" : "black", backgroundColor: targetDoc.keyFrameEditing ? PresColor.DarkBlue : PresColor.LightBlue }}
-                                        onClick={action(() => targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing)} >
-                                        {NumCast(targetDoc._currentFrame)}
-                                    </div>
-                                    <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc, activeItem); }}>
-                                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
-                                    </div>
-                                </div>
-                                <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
-                            </div>
-                            <div className="ribbon-frameList">
-                                {this.frameListHeader}
-                                {this.frameList}
-                            </div>
-                            <div className="ribbon-toggle" style={{ height: 20, backgroundColor: PresColor.LightBlue }} onClick={() => console.log(" TODO: play frames")}>Play</div>
-                        </div>
-                    </div>
-                </div>
-            );
-        }
-    }
-
-    @undoBatch
-    @action
-    switchActive = (color: ColorState) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const val = String(color.hex);
-        targetDoc["pres-text-color"] = val;
-        return true;
-    }
-    @undoBatch
-    @action
-    switchPresented = (color: ColorState) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const val = String(color.hex);
-        targetDoc["pres-text-viewed-color"] = val;
-        return true;
-    }
-
-    @computed get activeColorPicker() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        return !this.openActiveColorPicker ? (null) : <SketchPicker onChange={this.switchActive}
-            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
-                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
-                '#FFFFFF', '#f1efeb', 'transparent']}
-            color={StrCast(targetDoc["pres-text-color"])} />;
-    }
-
-    @computed get viewedColorPicker() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        return !this.openViewedColorPicker ? (null) : <SketchPicker onChange={this.switchPresented}
-            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
-                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
-                '#FFFFFF', '#f1efeb', 'transparent']}
-            color={StrCast(targetDoc["pres-text-viewed-color"])} />;
-    }
-
-    @action
-    turnOffEdit = (paths?: boolean) => {
-        // Turn off paths
-        if (paths) {
-            const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
-            if (srcContext) this.togglePath(srcContext, true);
-        }
-        // Turn off the progressivize editors for each document
-        this.childDocs.forEach((doc) => {
-            doc.editSnapZoomProgressivize = false;
-            doc.editZoomProgressivize = false;
-            const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
-            if (targetDoc) {
-                targetDoc.editZoomProgressivize = false;
-                // targetDoc.editScrollProgressivize = false;
-            }
-        });
-    }
-
-    //Toggle whether the user edits or not
-    @action
-    editZoomProgressivize = (e: React.MouseEvent) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        if (!targetDoc.editZoomProgressivize) {
-            if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true;
-            targetDoc.editZoomProgressivize = true;
-            activeItem.editZoomProgressivize = true;
-        } else {
-            targetDoc.editZoomProgressivize = false;
-            activeItem.editZoomProgressivize = false;
-        }
-    }
-
-    //Toggle whether the user edits or not
-    @action
-    editScrollProgressivize = (e: React.MouseEvent) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        if (!targetDoc.editScrollProgressivize) {
-            if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; }
-            targetDoc.editScrollProgressivize = true;
-        } else {
-            targetDoc.editScrollProgressivize = false;
-        }
-    }
-
-    //Progressivize Zoom
-    @action
-    progressivizeScroll = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        const activeItem: Doc = this.activeItem;
-        activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
-        const targetDoc: Doc = this.targetDoc;
-        targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize;
-        // CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc._currentFrame));
-        if (targetDoc.editScrollProgressivize) {
-            targetDoc.editScrollProgressivize = false;
-            targetDoc._currentFrame = 0;
-            targetDoc.lastFrame = 0;
-        }
-    }
-
-    //Progressivize Zoom
-    @action
-    progressivizeZoom = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        const activeItem: Doc = this.activeItem;
-        activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
-        const targetDoc: Doc = this.targetDoc;
-        targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
-        CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc);
-        if (activeItem.editZoomProgressivize) {
-            activeItem.editZoomProgressivize = false;
-            targetDoc._currentFrame = 0;
-            targetDoc.lastFrame = 0;
-        }
-    }
-
-    //Progressivize Child Docs
-    @action
-    editProgressivize = (e: React.MouseEvent) => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        targetDoc._currentFrame = targetDoc.lastFrame;
-        if (!targetDoc.editProgressivize) {
-            if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; }
-            targetDoc.editProgressivize = true;
-        } else {
-            targetDoc.editProgressivize = false;
-        }
-    }
-
-    @action
-    progressivizeChild = (e: React.MouseEvent) => {
-        e.stopPropagation();
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
-        if (!activeItem.presProgressivize) {
-            targetDoc.keyFrameEditing = false;
-            activeItem.presProgressivize = true;
-            targetDoc.presProgressivize = true;
-            targetDoc._currentFrame = 0;
-            docs.forEach((doc, i) => CollectionFreeFormDocumentView.setupKeyframes([doc], i, true));
-            targetDoc.lastFrame = targetDoc.lastFrame ? NumCast(targetDoc.lastFrame) : docs.length - 1;
-        } else {
-            // targetDoc.editProgressivize = false;
-            activeItem.presProgressivize = false;
-            targetDoc.presProgressivize = false;
-            targetDoc._currentFrame = 0;
-            targetDoc.keyFrameEditing = true;
-        }
-    }
-
-    @action
-    checkMovementLists = (doc: Doc, xlist: any, ylist: any) => {
-        const x: List<number> = xlist;
-        const y: List<number> = ylist;
-        const tags: JSX.Element[] = [];
-        let pathPoints = ""; //List of all of the pathpoints that need to be added
-        for (let i = 0; i < x.length - 1; i++) {
-            if (y[i] || x[i]) {
-                if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33);
-                else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33);
-                tags.push(<div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>{i}</div>);
-            }
-        }
-        tags.push(<svg style={{ overflow: 'visible', position: 'absolute' }}><polyline
-            points={pathPoints}
-            style={{
-                position: 'absolute',
-                opacity: 1,
-                stroke: "#000000",
-                strokeWidth: 2,
-                strokeDasharray: '10 5',
-            }}
-            fill="none"
-        /></svg>);
-        return tags;
-    }
-
-    @observable
-    toggleDisplayMovement = (doc: Doc) => {
-        if (doc.displayMovement) doc.displayMovement = false;
-        else doc.displayMovement = true;
-    }
-
-    @action
-    checkList = (doc: Doc, list: any): number => {
-        const x: List<number> = list;
-        if (x && x.length >= NumCast(doc._currentFrame) + 1) {
-            return x[NumCast(doc._currentFrame)];
-        } else if (x) {
-            x.length = NumCast(doc._currentFrame) + 1;
-            x[NumCast(doc._currentFrame)] = x[NumCast(doc._currentFrame) - 1];
-            return x[NumCast(doc._currentFrame)];
-        } else return 100;
-    }
-
-    @computed get progressivizeChildDocs() {
-        const targetDoc: Doc = this.targetDoc;
-        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
-        const tags: JSX.Element[] = [];
-        docs.forEach((doc, index) => {
-            if (doc["x-indexed"] && doc["y-indexed"]) {
-                tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? "block" : "none" }}>{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}</div>);
-            }
-            tags.push(
-                <div className="progressivizeButton" key={index} onPointerLeave={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? PresColor.LightBlue : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
-                    <div className="progressivizeButton-prev"><FontAwesomeIcon icon={"caret-left"} size={"lg"} onClick={e => { e.stopPropagation(); this.prevAppearFrame(doc, index); }} /></div>
-                    <div className="progressivizeButton-frame">{doc.appearFrame}</div>
-                    <div className="progressivizeButton-next"><FontAwesomeIcon icon={"caret-right"} size={"lg"} onClick={e => { e.stopPropagation(); this.nextAppearFrame(doc, index); }} /></div>
-                </div>);
-        });
-        return tags;
-    }
-
-    @action
-    nextAppearFrame = (doc: Doc, i: number): void => {
-        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
-        const appearFrame = Cast(doc.appearFrame, "number", null);
-        if (appearFrame === undefined) {
-            doc.appearFrame = 0;
-        }
-        doc.appearFrame = appearFrame + 1;
-        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
-    }
-
-    @action
-    prevAppearFrame = (doc: Doc, i: number): void => {
-        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
-        // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
-        const appearFrame = Cast(doc.appearFrame, "number", null);
-        if (appearFrame === undefined) {
-            doc.appearFrame = 0;
-        }
-        doc.appearFrame = Math.max(0, appearFrame - 1);
-        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
-    }
-
-    @action
-    updateOpacityList = (list: any, frame: number) => {
-        const x: List<number> = list;
-        if (x && x.length >= frame) {
-            for (let i = 0; i < x.length; i++) {
-                if (i < frame) {
-                    x[i] = 0;
-                } else if (i >= frame) {
-                    x[i] = 1;
-                }
-            }
-            list = x;
-        } else {
-            x.length = frame + 1;
-            for (let i = 0; i < x.length; i++) {
-                if (i < frame) {
-                    x[i] = 0;
-                } else if (i >= frame) {
-                    x[i] = 1;
-                }
-            }
-            list = x;
-        }
-    }
-
-    @computed get moreInfoDropdown() {
-        return (<div></div>);
-    }
-
-    @computed
-    get toolbarWidth(): number {
-        const width = this.props.PanelWidth();
-        return width;
-    }
-
-    @action
-    toggleProperties = () => {
-        if (CurrentUserUtils.propertiesWidth > 0) {
-            CurrentUserUtils.propertiesWidth = 0;
-        } else {
-            CurrentUserUtils.propertiesWidth = 250;
-        }
-    }
-
-    @computed get toolbar() {
-        const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left";
-        const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Presentation Panel" : "Open Presentation Panel";
-        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        const isMini: boolean = this.toolbarWidth <= 100;
-        const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === Doc.UserDoc().activePresentation);
-        return (mode === CollectionViewType.Carousel3D) ? (null) : (
-            <div id="toolbarContainer" className={'presBox-toolbar'}>
-                {/* <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
-                    <FontAwesomeIcon icon={"plus"} />
-                    <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
-                </div></Tooltip> */}
-                <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}>
-                    <div style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? PresColor.DarkBlue : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
-                        <FontAwesomeIcon icon={"exchange-alt"} />
-                    </div>
-                </Tooltip>
-                {isMini ? (null) :
-                    <>
-                        <div className="toolbar-divider" />
-                        {/* <Tooltip title={<><div className="dash-tooltip">{this._expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
-                            <div className={"toolbar-button"}
-                                style={{ color: this._expandBoolean ? PresColors.DarkBlue : 'white' }}
-                                onClick={this.toggleExpandMode}>
-                                <FontAwesomeIcon icon={"eye"} />
-                            </div>
-                        </Tooltip>
-                        <div className="toolbar-divider" /> */}
-                        <Tooltip title={<><div className="dash-tooltip">{presKeyEvents ? "Keys are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}</div></>}>
-                            <div className="toolbar-button" style={{ cursor: presKeyEvents ? 'default' : 'pointer', position: 'absolute', right: 30, fontSize: 16 }}>
-                                <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"keyboard"} style={{ color: presKeyEvents ? PresColor.DarkBlue : 'white' }} />
-                            </div>
-                        </Tooltip>
-                        <Tooltip title={<><div className="dash-tooltip">{propTitle}</div></>}>
-                            <div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}>
-                                <FontAwesomeIcon className={"toolbar-thumbtack"} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? PresColor.DarkBlue : 'white' }} />
-                            </div>
-                        </Tooltip>
-                    </>
-                }
-            </div>
-        );
-    }
-
-    /**
-     * Top panel containes:
-     * viewPicker: The option to choose between List and Slides view for the presentaiton trail
-     * presentPanel: The button to start the presentation / open minimized view of the presentation
-     */
-    @computed get topPanel() {
-        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        const isMini: boolean = this.toolbarWidth <= 100;
-        return (
-            <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? "none" : undefined }}>
-                {isMini ? (null) : <select className="presBox-viewPicker"
-                    style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
-                    onPointerDown={e => e.stopPropagation()}
-                    onChange={this.viewChanged}
-                    value={mode}>
-                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
-                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}>3D Carousel</option>
-                </select>}
-                <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
-                    <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
-                        <div className="presBox-button-left"
-                            onClick={undoBatch(() => {
-                                if (this.childDocs.length) {
-                                    this.layoutDoc.presStatus = "manual";
-                                    this.gotoDocument(this.itemIndex, this.activeItem);
-                                }
-                            })}>
-                            <FontAwesomeIcon icon={"play-circle"} />
-                            <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
-                        </div>
-                        {(mode === CollectionViewType.Carousel3D || isMini) ? (null) : <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`}
-                            onClick={(action(() => {
-                                if (this.childDocs.length) this.presentTools = !this.presentTools;
-                            }))}>
-                            <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
-                            {this.presentDropdown}
-                        </div>}
-                    </span>
-                    {this.playButtons}
-                </div>
-            </div>
-        );
-    }
-
-    @action
-    getList = (list: any): List<number> => {
-        const x: List<number> = list;
-        return x;
-    }
-
-    @action
-    updateList = (list: any): List<number> => {
-        const targetDoc: Doc = this.targetDoc;
-        const x: List<number> = list;
-        x.length + 1;
-        x[x.length - 1] = NumCast(targetDoc._scrollY);
-        return x;
-    }
-
-    @action
-    newFrame = () => {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const type: string = StrCast(targetDoc.type);
-        if (!activeItem.frameList) activeItem.frameList = new List<number>();
-        switch (type) {
-            case (DocumentType.PDF || DocumentType.RTF || DocumentType.WEB):
-                this.updateList(activeItem.frameList);
-                break;
-            case DocumentType.COL:
-                break;
-            default:
-                break;
-        }
-    }
-
-    @computed get frameListHeader() {
-        return (<div className="frameList-header">
-            &nbsp; Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : (null)}
-            <div className={"frameList-headerButtons"}>
-                <Tooltip title={<><div className="dash-tooltip">{"Add frame by example"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); this.newFrame(); }}>
-                    <FontAwesomeIcon icon={"plus"} onPointerDown={e => e.stopPropagation()} />
-                </div></Tooltip>
-                <Tooltip title={<><div className="dash-tooltip">{"Edit in collection"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); console.log('New frame'); }}>
-                    <FontAwesomeIcon icon={"edit"} onPointerDown={e => e.stopPropagation()} />
-                </div></Tooltip>
-            </div>
-        </div>);
-    }
-
-    @computed get frameList() {
-        const activeItem: Doc = this.activeItem;
-        const targetDoc: Doc = this.targetDoc;
-        const frameList: List<number> = this.getList(activeItem.frameList);
-        if (frameList) {
-            const frameItems = frameList.map((value) =>
-                <div className="framList-item">
-
-                </div>
-            );
-            return (
-
-                <div className="frameList-container">
-                    {frameItems}
-                </div>
-            );
-        } else return (null);
-
-    }
-
-    @computed get playButtonFrames() {
-        const targetDoc: Doc = this.targetDoc;
-        return (
-            <>
-                {this.targetDoc ? <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
-                    <div>{targetDoc._currentFrame}</div>
-                    <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
-                    <div>{targetDoc.lastFrame}</div>
-                </div> : null}
-            </>
-        );
-    }
-
-    @computed get playButtons() {
-        const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
-        const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
-        // Case 1: There are still other frames and should go through all frames before going to next slide
-        return (<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
-            <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? PresColor.DarkBlue : 'white' }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
-            <div className="presPanel-divider"></div>
-            <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div>
-            <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? "pause" : "play"} /></div></Tooltip>
-            <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
-            <div className="presPanel-divider"></div>
-            <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip>
-            <div
-                className="presPanel-button-text"
-                onClick={() => this.gotoDocument(0, this.activeItem)}
-                style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
-                Slide {this.itemIndex + 1} / {this.childDocs.length}
-                {this.playButtonFrames}
-            </div>
-            <div className="presPanel-divider"></div>
-            {this.props.PanelWidth() > 250 ? <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT</div>
-                : <div className="presPanel-button" onClick={undoBatch(action(() => this.layoutDoc.presStatus = "edit"))}>
-                    <FontAwesomeIcon icon={"times"} />
-                </div>}
-        </div>);
-    }
-
-    @action
-    startOrPause = () => {
-        if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
-        else this.pauseAutoPres();
-    }
-
-    render() {
-        // calling this method for keyEvents
-        this.isPres;
-        // needed to ensure that the childDocs are loaded for looking up fields
-        this.childDocs.slice();
-        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
-        const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === Doc.UserDoc().activePresentation);
-        const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
-        const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
-        return CurrentUserUtils.OverlayDocs.includes(this.rootDoc) ?
-            <div className="miniPres">
-                <div className="presPanelOverlay" style={{ display: "inline-flex", height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + PresColor.DarkBlue : undefined }}>
-                    <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? PresColor.DarkBlue : undefined }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
-                    <div className="presPanel-divider"></div>
-                    <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div>
-                    <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div></Tooltip>
-                    <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
-                    <div className="presPanel-divider"></div>
-                    <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip>
-                    <div className="presPanel-button-text">
-                        Slide {this.itemIndex + 1} / {this.childDocs.length}
-                        {this.playButtonFrames}
-                    </div>
-                    <div className="presPanel-divider"></div>
-                    <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.updateMinimize(); this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); }))}>EXIT</div>
-                </div>
-            </div>
-            :
-            <div className="presBox-cont" style={{ minWidth: CurrentUserUtils.OverlayDocs.includes(this.layoutDoc) ? 240 : undefined }} >
-                {this.topPanel}
-                {this.toolbar}
-                {this.newDocumentToolbarDropdown}
-                <div className="presBox-listCont">
-                    {mode !== CollectionViewType.Invalid ?
-                        <CollectionView {...this.props}
-                            ContainingCollectionDoc={this.props.Document}
-                            PanelWidth={this.props.PanelWidth}
-                            PanelHeight={this.panelHeight}
-                            childIgnoreNativeSize={true}
-                            moveDocument={returnFalse}
-                            childFitWidth={returnTrue}
-                            childOpacity={returnOne}
-                            childLayoutTemplate={this.childLayoutTemplate}
-                            filterAddDocument={this.addDocumentFilter}
-                            removeDocument={returnFalse}
-                            dontRegisterView={true}
-                            focus={this.selectElement}
-                            ScreenToLocalTransform={this.getTransform}
-                        />
-                        : (null)
-                    }
-                </div>
-            </div>;
-    }
-}
-Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, data: Doc) {
-    if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data);
-    if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 35 : 31;
-    if (field === 'presStatus') return container.presStatus;
-    if (field === '_itemIndex') return container._itemIndex;
-    if (field === 'presBox') return container;
-    return undefined;
-});
\ No newline at end of file
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 59b2d3753..d1c91cbb9 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -963,7 +963,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
             this.createHighlighterButton(),
             this.createLinkButton(),
             this.createBrushButton(),
-            <div className="richTextMenu-divider" key="divider 2" />,
+            <div className="collectionMenu-divider" key="divider 2" />,
             this.createButton("align-left", "Align Left", this.activeAlignment === "left", this.alignLeft),
             this.createButton("align-center", "Align Center", this.activeAlignment === "center", this.alignCenter),
             this.createButton("align-right", "Align Right", this.activeAlignment === "right", this.alignRight),
@@ -976,7 +976,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
         const row2 = <div className="antimodeMenu-row row-2" key="row2">
             {this.collapsed ? this.getDragger() : (null)}
             <div key="row 2" style={{ display: this.collapsed ? "none" : undefined }}>
-                <div className="richTextMenu-divider" key="divider 3" />
+                <div className="collectionMenu-divider" key="divider 3" />
                 {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size", action((val: string) => {
                     this.activeFontSize = val;
                     SelectionManager.Views().map(dv => dv.props.Document._fontSize = val);
@@ -985,12 +985,12 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps>   {
                     this.activeFontFamily = val;
                     SelectionManager.Views().map(dv => dv.props.Document._fontFamily = val);
                 })),
-                <div className="richTextMenu-divider" key="divider 4" />,
+                <div className="collectionMenu-divider" key="divider 4" />,
                 this.createNodesDropdown(this.activeListType, this.listTypeOptions, "list type", () => ({})),
                 this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer),
                 this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),
-                this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule),
-                <div className="richTextMenu-divider" key="divider 5" />,]}
+                this.createButton("minus", "Horizontal Rule", undefined, this.insertHorizontalRule)
+                ]}
             </div>
             {/* <div key="collapser">
                 {<div key="collapser">
diff --git a/src/client/views/nodes/trails/PresBox.scss b/src/client/views/nodes/trails/PresBox.scss
new file mode 100644
index 000000000..06932d145
--- /dev/null
+++ b/src/client/views/nodes/trails/PresBox.scss
@@ -0,0 +1,1243 @@
+@import "../../global/globalCssVariables";
+
+.presBox-cont {
+    cursor: auto;
+    position: absolute;
+    display: block;
+    pointer-events: inherit;
+    z-index: 2;
+    font-family: Roboto;
+    width: 100%;
+    min-width: 20px;
+    height: 100%;
+    min-height: 35px;
+    letter-spacing: 2px;
+    overflow: hidden;
+    transition: 0.7s opacity ease;
+
+    .presBox-listCont {
+        position: relative;
+        height: calc(100% - 67px);
+        width: 100%;
+    }
+
+    .presBox-toolbar-dropdown {
+        border-radius: 5px;
+        background-color: white;
+        transform: translate(8px, -5px);
+        box-shadow: 1px 1px 4px 4px rgba(0, 0, 0, 0.25);
+        z-index: 1000;
+        width: calc(100% - 50px);
+        height: max-content;
+        justify-self: center;
+        letter-spacing: normal;
+        height: max-content;
+        font-weight: 500;
+        position: relative;
+        font-size: 13;
+    }
+
+    .presBox-toolbar {
+        position: relative;
+        display: inline-flex;
+        align-items: center;
+        height: 30px;
+        width: 100%;
+        color: $white;
+        background-color: $dark-gray;
+
+        .toolbar-button {
+            cursor: pointer;
+            margin-left: 10px;
+            margin-right: 10px;
+            letter-spacing: 0;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            transition: 0.5s;
+        }
+
+        .toolbar-button.active {
+            color: $light-blue;
+            background-color: white;
+            border-radius: 100%;
+        }
+
+        .toolbar-transitionButtons {
+            display: block;
+
+            .toolbar-transition {
+                display: flex;
+                font-size: 10;
+                width: 100;
+                background-color: rgba(0, 0, 0, 0);
+                min-width: max-content;
+
+                .toolbar-icon {
+                    margin-right: 5px;
+                }
+            }
+        }
+    }
+
+    .toolbar-moreInfo {
+        position: absolute;
+        right: 5px;
+        display: flex;
+        width: max-content;
+        height: 25px;
+        justify-content: center;
+        transform: rotate(90deg);
+        align-items: center;
+        transition: 0.7s ease;
+
+        .toolbar-moreInfoBall {
+            width: 4px;
+            height: 4px;
+            border-radius: 100%;
+            background-color: white;
+            margin: 1px;
+            position: relative;
+        }
+    }
+
+    .toolbar-moreInfo.active {
+        transform: rotate(0deg);
+    }
+
+    .toolbar-divider {
+        border-left: solid $medium-gray 0.5px;
+        height: 20px;
+    }
+}
+
+.dropdown {
+    font-size: 10;
+    margin-left: 5px;
+    color: $medium-gray;
+    transition: 0.5s ease;
+}
+
+.dropdown.active {
+    transform: rotate(180deg);
+    color: $light-blue;
+    opacity: 0.8;
+}
+
+.presBox-radioButtons {
+    font-size: 10px;
+    font-weight: 200;
+    // background-color: rgba(0, 0, 0, 0.1);
+
+    .checkbox-container {
+        margin-left: 10px;
+        display: inline-flex;
+        width: 100%;
+        height: 20px;
+        align-items: center;
+    }
+
+    .checkbox-dropdown {
+        display: flex;
+        width: 100%;
+        align-items: flex-end;
+        gap: 5px;
+
+        .presBox-viewPicker {
+            width: calc(100% - 120px);
+            min-width: 30px;
+        }
+    }
+}
+
+.presBox-ribbon {
+    position: relative;
+    display: inline;
+    font-family: Roboto;
+    z-index: 100;
+    transition: 0.7s;
+
+    .ribbon-doubleButton {
+        display: inline-flex;
+    }
+
+    .presBox-reactiveGrid {
+        display: grid;
+        justify-content: flex-start;
+        align-items: center;
+        grid-template-columns: repeat(auto-fit, 70px);
+    }
+
+    .ribbon-colorBox {
+        cursor: pointer;
+        border: solid 1px $black;
+        display: flex;
+        margin-left: 5px;
+        margin-top: 5px;
+        margin-bottom: 5px;
+        justify-content: center;
+        align-items: center;
+        height: 15px;
+        width: 15px;
+        padding: 0px;
+        transform: translate(2px, 3px);
+    }
+
+    .ribbon-property {
+        font-size: 11;
+        font-weight: 200;
+        height: 20;
+        background-color: $white;
+        color: $black;
+        border: solid 1px $black;
+        display: flex;
+        margin-left: 5px;
+        margin-top: 5px;
+        margin-bottom: 5px;
+        width: max-content;
+        justify-content: center;
+        align-items: center;
+        padding-right: 10px;
+        padding-left: 10px;
+    }
+
+    .ribbon-propertyUpDown {
+        height: 20;
+        width: 20;
+        margin-top: 5px;
+        display: grid;
+        grid-template-rows: 10px 10px;
+
+        .ribbon-propertyUpDownItem {
+            cursor: pointer;
+            color: white;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            height: 100%;
+            width: 100%;
+            background: $black;
+        }
+
+        .ribbon-propertyUpDownItem:hover {
+            background: $medium-gray;
+            transform: scale(1.05);
+        }
+    }
+
+    .presBox-subheading {
+        font-size: 11;
+        font-weight: 400;
+        margin-top: 10px;
+    }
+
+    @media screen and (-webkit-min-device-pixel-ratio:0) {
+
+        .multiThumb-slider {
+            display: grid;
+            background-color: $white;
+            height: 10px;
+            border-radius: 10px;
+            overflow: hidden;
+
+            .toolbar-slider {
+                margin-top: 0px;
+                background: none;
+                -webkit-appearance: none;
+                pointer-events: none;
+            }
+
+            .toolbar-slider.start::-webkit-slider-thumb {
+                width: 10px;
+                pointer-events: auto;
+                -webkit-appearance: none;
+                height: 10px;
+                cursor: ew-resize;
+                background: $medium-blue;
+                box-shadow: -100vw 0 0 100vw $white;
+            }
+
+            .toolbar-slider.end::-webkit-slider-thumb {
+                width: 10px;
+                pointer-events: auto;
+                -webkit-appearance: none;
+                height: 10px;
+                cursor: ew-resize;
+                background: $medium-blue;
+                box-shadow: -100vw 0 0 100vw $light-blue;
+            }
+        }
+
+        .toolbar-slider {
+            margin-top: 5px;
+            position: relative;
+            align-self: center;
+            justify-self: left;
+            overflow: hidden;
+            width: 100%;
+            height: 10px;
+            border-radius: 10px;
+            -webkit-appearance: none;
+            background-color: $white;
+        }
+
+        .toolbar-slider:focus {
+            outline: none;
+        }
+
+        .toolbar-slider::-webkit-slider-runnable-track {
+            height: 10px;
+            -webkit-appearance: none;
+            margin-top: -1px;
+        }
+
+        .toolbar-slider::-webkit-slider-thumb {
+            width: 10px;
+            pointer-events: auto;
+            -webkit-appearance: none;
+            height: 10px;
+            cursor: ew-resize;
+            background: $medium-blue;
+            box-shadow: -100vw 0 0 100vw $light-blue;
+        }
+
+        .presBox-checkbox {
+            -webkit-appearance: none;
+            -webkit-user-select: none;
+            -moz-user-select: none;
+            -ms-user-select: none;
+            user-select: none;
+            margin: 0;
+            margin-right: 3px;
+            border-radius: 100%;
+            height: 15px;
+            width: 15px;
+            min-width: 15px;
+            cursor: pointer;
+            background: $white;
+        }
+
+        .presBox-checkbox:focus {
+            outline: none;
+        }
+
+        .presBox-checkbox:hover {
+            background: $light-gray;
+        }
+
+        .presBox-checkbox:checked {
+            background: $light-blue;
+        }
+    }
+
+
+
+    .slider-headers {
+        position: relative;
+        display: grid;
+        justify-content: space-between;
+        width: 100%;
+        height: max-content;
+        grid-template-columns: auto auto auto;
+        grid-template-rows: max-content;
+        font-weight: 100;
+        margin-top: 3px;
+        font-size: 10px;
+
+        .slider-block {
+            width: 63px;
+            border-radius: 5px;
+            text-align: center;
+            margin-bottom: 8px;
+            margin-top: 8px;
+        }
+
+        .slider-number {
+            border-radius: 3px;
+            width: 30px;
+            margin: auto;
+        }
+    }
+
+    .slider-value {
+        top: -20;
+        color: #2f86a2;
+        position: absolute;
+    }
+
+    .slider-value.none,
+    .slider-headers.none,
+    .toolbar-slider.none {
+        display: none;
+    }
+
+    .dropdown-header {
+        padding-bottom: 10px;
+        font-weight: 800;
+        text-align: center;
+        font-size: 16;
+        width: 90%;
+        color: $black;
+        transform: translate(5%, 0px);
+        border-bottom: solid 2px $medium-gray;
+    }
+
+
+    .ribbon-textInput {
+        border-radius: 2px;
+        height: 20px;
+        font-size: 11.5;
+        font-weight: 100;
+        align-self: center;
+        justify-self: left;
+        margin-top: 5px;
+        padding-left: 10px;
+        background-color: $white;
+        border: solid 1px $black;
+        min-width: 80px;
+        max-width: 200px;
+        width: 100%;
+    }
+
+    .presBox-input {
+        width: 30;
+        height: 100%;
+        background: none;
+        border: none;
+        text-align: right;
+    }
+
+    .presBox-input:focus {
+        outline: none;
+    }
+
+    .ribbon-frameSelector {
+        border: $black solid 1px;
+        width: 60px;
+        height: 20px;
+        margin-top: 5px;
+        display: grid;
+        grid-template-columns: auto 27px auto;
+        position: relative;
+        border-radius: 5px;
+        overflow: hidden;
+        align-items: center;
+        justify-self: left;
+
+        .fwdKeyframe,
+        .backKeyframe {
+            cursor: pointer;
+            position: relative;
+            height: 100%;
+            background: $white;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            text-align: center;
+            color: $black;
+        }
+
+        .numKeyframe {
+            cursor: pointer;
+            font-size: 10;
+            font-weight: 600;
+            position: relative;
+            color: $black;
+            display: flex;
+            width: 100%;
+            height: 100%;
+            text-align: center;
+            align-items: center;
+            justify-content: center;
+        }
+    }
+
+    .ribbon-final-box {
+        align-self: flex-start;
+        justify-self: center;
+        display: grid;
+        margin-top: 10px;
+        grid-template-rows: auto auto;
+        /* padding-left: 10px; */
+        /* padding-right: 10px; */
+        letter-spacing: normal;
+        min-width: max-content;
+        width: 100%;
+        font-size: 13;
+        font-weight: 500;
+        position: relative;
+
+
+        .ribbon-final-button {
+            cursor: pointer;
+            position: relative;
+            font-size: 11;
+            font-weight: normal;
+            letter-spacing: normal;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-bottom: 5px;
+            height: 25px;
+            color: white;
+            width: 100%;
+            max-width: 120;
+            padding-left: 10;
+            padding-right: 10;
+            border-radius: 10px;
+            background-color: $medium-gray;
+        }
+
+        .ribbon-final-button:hover {
+            transform: scale(1.05);
+            transition: all 0.4s;
+        }
+
+        .ribbon-final-button-hidden {
+            cursor: pointer;
+            position: relative;
+            font-size: 11;
+            font-weight: normal;
+            letter-spacing: normal;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            margin-bottom: 5px;
+            height: 25px;
+            color: $light-gray;
+            width: 100%;
+            max-width: 120;
+            padding-left: 10;
+            padding-right: 10;
+            border-radius: 10px;
+            background-color: $black;
+        }
+
+        .ribbon-final-button-hidden:hover {
+            transform: scale(1.05);
+            transition: all 0.4s;
+        }
+
+        .ribbon-frameList {
+            width: calc(100% - 5px);
+            height: 50px;
+            background-color: $white;
+            border: 1px solid $medium-gray;
+            grid-template-rows: max-content;
+
+            .frameList-header {
+                display: grid;
+                width: 100%;
+                height: 20px;
+                background-color: $medium-gray;
+
+                .frameList-headerButtons {
+                    display: flex;
+                    grid-column: 7;
+                    width: 60px;
+                    justify-self: right;
+                    justify-content: flex-end;
+
+                    .headerButton {
+                        cursor: pointer;
+                        position: relative;
+                        border-radius: 100%;
+                        z-index: 300;
+                        width: 15px;
+                        height: 15px;
+                        display: flex;
+                        font-size: 10px;
+                        justify-self: center;
+                        align-self: center;
+                        background-color: rgba(0, 0, 0, 0.5);
+                        color: white;
+                        justify-content: center;
+                        align-items: center;
+                        transition: 0.2s;
+                        margin-right: 3px;
+                    }
+
+                    .headerButton:hover {
+                        background-color: rgba(0, 0, 0, 1);
+                        transform: scale(1.15);
+                    }
+                }
+            }
+        }
+    }
+
+    .selectedList {
+        display: block;
+        min-width: 50;
+        max-width: 120;
+        height: 70;
+        overflow-y: scroll;
+
+        .selectedList-items {
+            font-size: 7;
+            font-weight: normal;
+        }
+    }
+
+    .ribbon-button {
+        cursor: pointer;
+        font-size: 10.5;
+        font-weight: 300;
+        height: 20;
+        background-color: $medium-gray;
+        color: white;
+        display: flex;
+        margin-top: 5px;
+        margin-bottom: 5px;
+        border-radius: 5px;
+        margin-right: 5px;
+        width: max-content;
+        justify-content: center;
+        align-items: center;
+        padding-right: 10px;
+        padding-left: 10px;
+    }
+
+    .ribbon-button:hover {
+        transform: scale(1.03);
+        transition: all 0.4s;
+        font-weight: 400;
+        opacity: 1;
+        color: $white;
+        background-color: $black;
+    }
+
+    .ribbon-toggle {
+        cursor: pointer;
+        font-size: 10.5;
+        font-weight: 200;
+        height: 20;
+        background-color: $white;
+        border: solid 1px rgba(0, 0, 0, 0.5);
+        display: flex;
+        color: $black;
+        margin-top: 5px;
+        margin-bottom: 5px;
+        border-radius: 5px;
+        margin-right: 5px;
+        width: max-content;
+        justify-content: center;
+        align-items: center;
+        padding-right: 10px;
+        padding-left: 10px;
+    }
+
+    .ribbon-toggle.active {
+        background-color: #aedef8;
+    }
+
+    .ribbon-toggle:hover {
+        transform: scale(1.03);
+        transition: all 0.4s;
+        border: solid 1px rgba(0, 0, 0, 0.75);
+    }
+
+    svg.svg-inline--fa.fa-thumbtack.fa-w-12.toolbar-thumbtack {
+        right: 40;
+        position: absolute;
+        transform: rotate(45deg);
+    }
+
+    .ribbon-box {
+        display: grid;
+        grid-template-rows: max-content auto;
+        justify-self: center;
+        margin-top: 10px;
+        padding-right: 10px;
+        letter-spacing: normal;
+        width: 100%;
+        height: max-content;
+        font-weight: 500;
+        position: relative;
+        font-size: 13;
+        padding-bottom: 10px;
+        border-bottom: solid 1px $dark-gray;
+
+        .presBox-dropdown:hover {
+            border: solid 1px $medium-blue;
+
+            .presBox-dropdownIcon {
+                color: $medium-blue;
+            }
+        }
+
+        .presBox-dropdown {
+            cursor: pointer;
+            display: grid;
+            grid-template-columns: auto 20%;
+            position: relative;
+            border: solid 1px $black;
+            background-color: $light-gray;
+            border-radius: 5px;
+            font-size: 10;
+            height: 25;
+            color: $black;
+            padding-left: 5px;
+            align-items: center;
+            margin-top: 5px;
+            margin-bottom: 5px;
+            font-weight: 200;
+            width: 100%;
+            min-width: max-content;
+            max-width: 200px;
+            overflow: visible;
+
+
+            .presBox-dropdownOption {
+                cursor: pointer;
+                font-size: 11;
+                display: block;
+                padding-left: 10px;
+                padding-right: 5px;
+                padding-top: 3;
+                padding-bottom: 3;
+            }
+
+            .presBox-dropdownOption:hover {
+                position: relative;
+                background-color: lightgrey;
+            }
+
+            .presBox-dropdownOption.active {
+                position: relative;
+                background-color: $light-blue;
+            }
+
+            .presBox-dropdownOptions {
+                position: absolute;
+                top: 23px;
+                left: -2px;
+                z-index: 200;
+                width: 85%;
+                min-width: max-content;
+                display: block;
+                background: #FFFFFF;
+                border: 0.5px solid #979797;
+                box-sizing: border-box;
+                box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
+            }
+
+            .presBox-dropdownIcon {
+                position: relative;
+                color: black;
+                align-self: center;
+                justify-self: center;
+                margin-right: 2px;
+            }
+        }
+    }
+}
+
+.presBox-ribbon.active {
+    display: grid;
+    grid-template-columns: auto auto auto auto auto;
+    grid-template-rows: 100%;
+    height: 100px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    border: solid 1px $black;
+    // overflow: auto; 
+
+    ::-webkit-scrollbar {
+        -webkit-appearance: none;
+        height: 3px;
+        width: 8px;
+    }
+
+    ::-webkit-scrollbar-thumb {
+        border-radius: 2px;
+    }
+}
+
+.dropdown-play-button {
+    cursor: pointer;
+    font-size: 12;
+    padding-left: 5px;
+    padding-right: 5px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    text-align: left;
+    justify-content: left;
+}
+
+.dropdown-play-button:hover {
+    background-color: lightgrey;
+}
+
+.presBox-button-left {
+    cursor: pointer;
+    position: relative;
+    align-self: flex-start;
+    justify-self: flex-start;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 4px;
+    padding-left: 7px;
+    padding-right: 7px;
+    border-bottom-right-radius: 0;
+    border-top-right-radius: 0;
+}
+
+.presBox-button-right {
+    cursor: pointer;
+    position: relative;
+    text-align: center;
+    border-left: solid 1px $medium-gray;
+    width: 20%;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    border-radius: 4px;
+    padding-left: 7px;
+    padding-right: 7px;
+    border-bottom-left-radius: 0;
+    border-top-left-radius: 0;
+}
+
+.presBox-button-right.active {
+    background-color: #223063;
+    border: #aedcf6 solid 1px;
+    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
+}
+
+.dropdown-play {
+    cursor: pointer;
+    right: 0px;
+    top: calc(100% + 2px);
+    display: none;
+    border-radius: 5px;
+    width: max-content;
+    min-height: 20px;
+    height: max-content;
+    box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.8);
+    z-index: 200;
+    background-color: white;
+    color: $black;
+    position: absolute;
+    overflow: hidden;
+}
+
+.dropdown-play.active {
+    display: block;
+}
+
+.open-layout {
+    cursor: pointer;
+    position: relative;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transform: translate(0px, -1px);
+    background-color: $white;
+    width: 40px;
+    height: 15px;
+    align-self: center;
+    justify-self: center;
+    border: solid 1px $black;
+    border-top: 0px;
+    border-bottom-right-radius: 7px;
+    border-bottom-left-radius: 7px;
+}
+
+.layout-container {
+    padding: 5px;
+    display: grid;
+    background-color: $white;
+    grid-template-columns: repeat(auto-fit, minmax(90px, 100px));
+    width: 100%;
+    border: solid 1px $black;
+    min-width: 100px;
+    overflow: hidden;
+
+    .layout:hover {
+        border: solid 2px $medium-blue;
+    }
+
+    .layout {
+        cursor: pointer;
+        align-self: center;
+        justify-self: center;
+        margin-top: 5;
+        margin-bottom: 5;
+        position: relative;
+        height: 55px;
+        min-width: 90px;
+        width: 90px;
+        overflow: hidden;
+        background-color: white;
+        border: solid $medium-gray 1px;
+        display: grid;
+        grid-template-rows: auto;
+        align-items: center;
+        text-align: center;
+
+        .title {
+            position: relative;
+            align-self: end;
+            padding-left: 3px;
+            margin-left: 3px;
+            margin-right: 3px;
+            height: 13;
+            font-size: 12;
+            display: flex;
+            background-color: $white;
+        }
+
+        .subtitle {
+            align-self: flex-start;
+            position: relative;
+            padding-left: 3px;
+            margin-left: 3px;
+            margin-right: 3px;
+            font-weight: 400;
+            height: 13;
+            font-size: 9;
+            display: flex;
+            background-color: $white;
+        }
+
+        .content {
+            position: relative;
+            font-weight: 200;
+            align-self: flex-start;
+            padding-left: 3px;
+            margin-left: 3px;
+            margin-right: 3px;
+            height: 13;
+            font-size: 10;
+            display: flex;
+            background-color: $white;
+            height: 33;
+            text-align: left;
+            font-size: 8px;
+        }
+    }
+}
+
+.presBox-buttons {
+    position: relative;
+    width: 100%;
+    background: $medium-gray;
+    min-height: 35px;
+    padding-top: 5px;
+    padding-bottom: 5px;
+    display: grid;
+    grid-template-columns: auto auto;
+
+    .presBox-viewPicker {
+        cursor: pointer;
+        height: 25;
+        position: relative;
+        display: inline-block;
+        grid-column: 1;
+        border-radius: 5px;
+        min-width: 15px;
+        max-width: 100px;
+        left: 8px;
+    }
+
+    .presBox-presentPanel {
+        display: flex;
+        justify-self: end;
+        width: 100%;
+        max-width: 300px;
+        min-width: 150px;
+    }
+
+
+
+    select {
+        background: $dark-gray;
+        color: $white;
+    }
+
+    .presBox-button {
+        cursor: pointer;
+        height: 25px;
+        border-radius: 5px;
+        display: none;
+        justify-content: center;
+        align-content: center;
+        align-items: center;
+        text-align: center;
+        letter-spacing: normal;
+        width: inherit;
+        background: $dark-gray;
+        color: $white;
+    }
+
+    .presBox-button.active {
+        display: flex;
+    }
+
+    .presBox-button.active:hover {
+        background-color: $medium-blue;
+    }
+
+    .presBox-button.edit {
+        display: flex;
+        max-width: 25px;
+    }
+
+    .presBox-button.present {
+        display: flex;
+        width: max-content;
+        position: absolute;
+        right: 10px;
+
+        .present-icon {
+            margin-right: 7px;
+        }
+    }
+
+
+
+    .collectionViewBaseChrome-viewPicker {
+        min-width: 50;
+        width: 5%;
+        height: 25;
+        position: relative;
+        display: inline-block;
+        left: 8px;
+    }
+}
+
+.presBox-backward,
+.presBox-forward {
+    width: 25px;
+    border-radius: 5px;
+    top: 50%;
+    position: absolute;
+    display: inline-block;
+}
+
+.presBox-backward {
+    left: 5;
+}
+
+.presBox-forward {
+    right: 5;
+}
+
+// CSS adjusted for mobile devices
+@media only screen and (max-device-width: 480px) {
+    .presBox-cont .presBox-buttons {
+        position: absolute;
+        top: 70%;
+        left: 50%;
+        transform: translate(-50%, 0);
+        width: max-content;
+        height: 15%;
+        z-index: 2;
+        align-items: center;
+        background: rgba(0, 0, 0, 0);
+        display: inline-flex;
+
+        .presBox-button {
+            margin-top: 5%;
+            height: 250;
+            width: 300;
+            font-size: 100;
+            display: flex;
+            align-items: center;
+            background: $dark-gray;
+            color: $white;
+        }
+
+        .presBox-viewPicker {
+            top: -70;
+            left: 2.5%;
+            height: 50;
+            width: 95%;
+            font-size: 30px;
+            position: absolute;
+            min-width: 50px;
+        }
+    }
+
+    .presBox-cont .presBox-listCont {
+        top: 50;
+        height: calc(100% - 80px);
+    }
+
+    .input,
+    .select {
+        font-size: 100%;
+    }
+}
+
+.miniPres {
+    cursor: grab;
+    position: absolute;
+    right: 10;
+    top: 10;
+    opacity: 0.1;
+    transition: all 0.4s;
+    color: $white;
+}
+
+.miniPres:hover {
+    opacity: 1;
+}
+
+.presPanelOverlay {
+    background-color: $dark-gray;
+    color: $white;
+    border-radius: 5px;
+    grid-template-rows: 100%;
+    height: 25;
+    width: max-content;
+    min-width: max-content;
+    justify-content: space-evenly;
+    align-items: center;
+    display: flex;
+    position: absolute;
+    right: 10px;
+    transition: all 0.2s;
+
+    .presPanel-button-text {
+        cursor: pointer;
+        display: flex;
+        height: 20;
+        width: max-content;
+        font-family: Roboto;
+        font-weight: 400;
+        margin-left: 3px;
+        margin-right: 3px;
+        padding-right: 3px;
+        padding-left: 3px;
+        letter-spacing: normal;
+        border-radius: 5px;
+        align-items: center;
+        justify-content: center;
+        transition: all 0.3s;
+    }
+
+    .presPanel-divider {
+        width: 0.5px;
+        height: 80%;
+        border-right: solid 1px $medium-gray;
+    }
+
+    .presPanel-button-frame {
+        justify-self: center;
+        align-self: center;
+        align-items: center;
+        display: grid;
+        grid-template-columns: auto auto auto;
+        justify-content: space-around;
+        font-size: 11;
+        margin-left: 7;
+        width: 30;
+        height: 85%;
+        background-color: rgba(91, 157, 221, 0.4);
+        border-radius: 5px;
+    }
+
+    .presPanel-button {
+        cursor: pointer;
+        display: flex;
+        height: 20;
+        min-width: 20;
+        margin-left: 3px;
+        margin-right: 3px;
+        border-radius: 100%;
+        align-items: center;
+        justify-content: center;
+        transition: all 0.3s;
+    }
+
+    .presPanel-button:hover {
+        background-color: $medium-gray;
+        transform: scale(1.2);
+    }
+
+    .presPanel-button-text:hover {
+        background-color: $medium-gray;
+    }
+
+
+}
+
+// .miniPres {
+//     cursor: grab;
+//     position: absolute;
+//     overflow: hidden;
+//     right: 10;
+//     top: 10;
+//     opacity: 0.1;
+//     transition: all 0.4s;
+//     /* border: solid 1px; */
+//     color: white;
+//     /* box-shadow: black 0.4vw 0.4vw 0.8vw; */
+
+//     .miniPresOverlay {
+//         display: grid;
+//         grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
+//         grid-template-rows: 100%;
+//         height: 100%;
+//         justify-items: center;
+//         align-items: center;
+
+//         .miniPres-button-text {
+//             cursor: pointer;
+//             display: flex;
+//             height: 20;
+//             font-weight: 400;
+//             min-width: 100%;
+//             border-radius: 5px;
+//             align-items: center;
+//             justify-content: center;
+//             transition: all 0.3s;
+//         }
+
+//         .miniPres-button-frame {
+//             justify-self: center;
+//             align-self: center;
+//             align-items: center;
+//             display: grid;
+//             grid-template-columns: auto auto auto;
+//             justify-content: space-around;
+//             font-size: 11;
+//             margin-left: 7;
+//             width: 30;
+//             height: 85%;
+//             background-color: rgba(91, 157, 221, 0.4);
+//             border-radius: 5px;
+//         }
+
+//         .miniPres-divider {
+//             width: 0.5px;
+//             height: 80%;
+//             border-right: solid 2px #5a5a5a;
+//         }
+
+//         .miniPres-button {
+//             cursor: pointer;
+//             display: flex;
+//             height: 20;
+//             min-width: 20;
+//             border-radius: 100%;
+//             align-items: center;
+//             justify-content: center;
+//             transition: all 0.3s;
+//         }
+
+//         .miniPres-button:hover {
+//             background-color: #5a5a5a;
+//         }
+
+//         .miniPres-button-text:hover {
+//             background-color: #5a5a5a;
+//         }
+//     }
+// }
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
new file mode 100644
index 000000000..5cb9866f8
--- /dev/null
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -0,0 +1,2440 @@
+import React = require("react");
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tooltip } from "@material-ui/core";
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { ColorState, SketchPicker } from "react-color";
+import { Bounce, Fade, Flip, LightSpeed, Roll, Rotate, Zoom } from 'react-reveal';
+import { Doc, DocListCast, DocListCastAsync, FieldResult } from "../../../../fields/Doc";
+import { documentSchema } from "../../../../fields/documentSchemas";
+import { InkTool } from "../../../../fields/InkField";
+import { List } from "../../../../fields/List";
+import { PrefetchProxy } from "../../../../fields/Proxy";
+import { listSpec, makeInterface } from "../../../../fields/Schema";
+import { ScriptField } from "../../../../fields/ScriptField";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { emptyFunction, returnFalse, returnOne, returnTrue } from '../../../../Utils';
+import { Docs } from "../../../documents/Documents";
+import { DocumentType } from "../../../documents/DocumentTypes";
+import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
+import { DocumentManager } from "../../../util/DocumentManager";
+import { Scripting } from "../../../util/Scripting";
+import { SelectionManager } from "../../../util/SelectionManager";
+import { undoBatch, UndoManager } from "../../../util/UndoManager";
+import { CollectionDockingView } from "../../collections/CollectionDockingView";
+import { CollectionView, CollectionViewType } from "../../collections/CollectionView";
+import { TabDocView } from "../../collections/TabDocView";
+import { ViewBoxBaseComponent } from "../../DocComponent";
+import { Colors } from "../../global/globalEnums";
+import { LightboxView } from "../../LightboxView";
+import { CollectionFreeFormDocumentView } from "../CollectionFreeFormDocumentView";
+import { FieldView, FieldViewProps } from '../FieldView';
+import "./PresBox.scss";
+import Color = require("color");
+import { PresEffect, PresStatus, PresMovement } from "./PresEnums";
+
+export class PinProps {
+    audioRange?: boolean;
+    unpin?: boolean;
+    setPosition?: boolean;
+    hidePresBox?: boolean;
+}
+
+type PresBoxSchema = makeInterface<[typeof documentSchema]>;
+const PresBoxDocument = makeInterface(documentSchema);
+
+@observer
+export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>(PresBoxDocument) {
+    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresBox, fieldKey); }
+
+    static renderEffectsDoc(renderDoc: any, layoutDoc: Doc) {
+        const effectProps = {
+            left: layoutDoc.presEffectDirection === PresEffect.Left,
+            right: layoutDoc.presEffectDirection === PresEffect.Right,
+            top: layoutDoc.presEffectDirection === PresEffect.Top,
+            bottom: layoutDoc.presEffectDirection === PresEffect.Bottom,
+            opposite: true,
+            delay: layoutDoc.presTransition,
+            // when: this.layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc,
+        };
+        switch (layoutDoc.presEffect) {
+            case PresEffect.Zoom: return (<Zoom {...effectProps}>{renderDoc}</Zoom>);
+            case PresEffect.Fade: return (<Fade {...effectProps}>{renderDoc}</Fade>);
+            case PresEffect.Flip: return (<Flip {...effectProps}>{renderDoc}</Flip>);
+            case PresEffect.Rotate: return (<Rotate {...effectProps}>{renderDoc}</Rotate>);
+            case PresEffect.Bounce: return (<Bounce {...effectProps}>{renderDoc}</Bounce>);
+            case PresEffect.Roll: return (<Roll {...effectProps}>{renderDoc}</Roll>);
+            case PresEffect.Lightspeed: return (<LightSpeed {...effectProps}>{renderDoc}</LightSpeed>);
+            case PresEffect.None:
+            default: return renderDoc;
+        }
+    }
+    public static EffectsProvider(layoutDoc: Doc, renderDoc: any) {
+        return PresBox.Instance && layoutDoc === PresBox.Instance.childDocs[PresBox.Instance.itemIndex]?.presentationTargetDoc ?
+            PresBox.renderEffectsDoc(renderDoc, layoutDoc)
+            :
+            renderDoc;
+    }
+
+    @observable public static Instance: PresBox;
+
+    @observable _isChildActive = false;
+    @observable _moveOnFromAudio: boolean = true;
+    @observable _presTimer!: NodeJS.Timeout;
+    @observable _presKeyEventsActive: boolean = false;
+
+    @observable _selectedArray: ObservableMap = new ObservableMap<Doc, any>();
+    @observable _eleArray: HTMLElement[] = [];
+    @observable _dragArray: HTMLElement[] = [];
+    @observable _pathBoolean: boolean = false;
+    @observable _expandBoolean: boolean = false;
+
+    private _disposers: { [name: string]: IReactionDisposer } = {};
+    @observable private transitionTools: boolean = false;
+    @observable private newDocumentTools: boolean = false;
+    @observable private progressivizeTools: boolean = false;
+    @observable private openMovementDropdown: boolean = false;
+    @observable private openEffectDropdown: boolean = false;
+    @observable private presentTools: boolean = false;
+    @computed get childDocs() { return DocListCast(this.dataDoc[this.fieldKey]); }
+    @computed get tagDocs() {
+        const tagDocs: Doc[] = [];
+        for (const doc of this.childDocs) {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            tagDocs.push(tagDoc);
+        }
+        return tagDocs;
+    }
+    @computed get itemIndex() { return NumCast(this.rootDoc._itemIndex); }
+    @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); }
+    @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); }
+    @computed get scrollable(): boolean {
+        if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
+        else return false;
+    }
+    @computed get panable(): boolean {
+        if ((this.targetDoc.type === DocumentType.COL && this.targetDoc._viewType === CollectionViewType.Freeform) || this.targetDoc.type === DocumentType.IMG) return true;
+        else return false;
+    }
+    @computed get presElement() { return Cast(Doc.UserDoc().presElement, Doc, null); }
+    constructor(props: any) {
+        super(props);
+        if (Doc.UserDoc().activePresentation = this.rootDoc) runInAction(() => PresBox.Instance = this);
+        if (!this.presElement) { // create exactly one presElmentBox template to use by any and all presentations.
+            Doc.UserDoc().presElement = new PrefetchProxy(Docs.Create.PresElementBoxDocument({
+                title: "pres element template", type: DocumentType.PRESELEMENT, _xMargin: 0, isTemplateDoc: true, isTemplateForField: "data"
+            }));
+            // this script will be called by each presElement to get rendering-specific info that the PresBox knows about but which isn't written to the PresElement
+            // this is a design choice -- we could write this data to the presElements which would require a reaction to keep it up to date, and it would prevent
+            // the preselement docs from being part of multiple presentations since they would all have the same field, or we'd have to keep per-presentation data
+            // stored on each pres element.
+            (this.presElement as Doc).lookupField = ScriptField.MakeFunction("lookupPresBoxField(container, field, data)",
+                { field: "string", data: Doc.name, container: Doc.name });
+        }
+        this.props.Document.presentationFieldKey = this.fieldKey; // provide info to the presElement script so that it can look up rendering information about the presBox
+    }
+    @computed get selectedDocumentView() {
+        if (SelectionManager.Views().length) return SelectionManager.Views()[0];
+        if (this._selectedArray.size) return DocumentManager.Instance.getDocumentView(this.rootDoc);
+    }
+    @computed get isPres(): boolean {
+        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+        if (this.selectedDoc?.type === DocumentType.PRES) {
+            document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+            document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
+            return true;
+        }
+        return false;
+    }
+    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
+
+    @action
+    componentWillUnmount() {
+        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+        this._presKeyEventsActive = false;
+        this.resetPresentation();
+        // Turn of progressivize editors
+        this.turnOffEdit(true);
+        Object.values(this._disposers).forEach(disposer => disposer?.());
+    }
+
+    @action
+    componentDidMount() {
+        this.rootDoc.presBox = this.rootDoc;
+        this.rootDoc._forceRenderEngine = "timeline";
+        this.layoutDoc.presStatus = PresStatus.Edit;
+        this.layoutDoc._gridGap = 0;
+        this.layoutDoc._yMargin = 0;
+        this.turnOffEdit(true);
+        DocListCastAsync((Doc.UserDoc().myPresentations as Doc).data).then(pres =>
+            !pres?.includes(this.rootDoc) && Doc.AddDocToList(Doc.UserDoc().myPresentations as Doc, "data", this.rootDoc));
+        this._disposers.selection = reaction(() => SelectionManager.Views(),
+            views => views.some(view => view.props.Document === this.rootDoc) && this.updateCurrentPresentation());
+    }
+
+    @action
+    updateCurrentPresentation = (pres?: Doc) => {
+        if (pres) Doc.UserDoc().activePresentation = pres;
+        else Doc.UserDoc().activePresentation = this.rootDoc;
+        document.removeEventListener("keydown", PresBox.keyEventsWrapper, true);
+        document.addEventListener("keydown", PresBox.keyEventsWrapper, true);
+        this._presKeyEventsActive = true;
+        PresBox.Instance = this;
+    }
+
+    // There are still other internal frames and should go through all frames before going to next slide
+    nextInternalFrame = (targetDoc: Doc, activeItem: Doc) => {
+        const currentFrame = Cast(targetDoc?._currentFrame, "number", null);
+        const childDocs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        targetDoc._viewTransition = "all 1s";
+        setTimeout(() => targetDoc._viewTransition = undefined, 1010);
+        this.nextKeyframe(targetDoc, activeItem);
+        if (activeItem.presProgressivize) CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, targetDoc);
+        else targetDoc.keyFrameEditing = true;
+    }
+
+    _mediaTimer!: [NodeJS.Timeout, Doc];
+    // 'Play on next' for audio or video therefore first navigate to the audio/video before it should be played
+    startTempMedia = (targetDoc: Doc, activeItem: Doc) => {
+        const duration: number = NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime);
+        if ([DocumentType.VID, DocumentType.AUDIO].includes(targetDoc.type as any)) {
+            const targMedia = DocumentManager.Instance.getDocumentView(targetDoc);
+            targMedia?.ComponentView?.playFrom?.(NumCast(activeItem.presStartTime), NumCast(activeItem.presStartTime) + duration);
+        }
+        // if (targetDoc.type === DocumentType.AUDIO) {
+        //     if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
+        //     targetDoc._triggerAudio = NumCast(activeItem.presStartTime);
+        //     this._mediaTimer = [setTimeout(() => targetDoc._audioStop = true, duration * 1000), targetDoc];
+        // } else if (targetDoc.type === DocumentType.VID) {
+        //     targetDoc._triggerVideoStop = true;
+        //     setTimeout(() => targetDoc._currentTimecode = NumCast(activeItem.presStartTime), 10);
+        //     setTimeout(() => targetDoc._triggerVideo = true, 20);
+        //     this._mediaTimer = [setTimeout(() => targetDoc._triggerVideoStop = true, (duration * 1000) + 20), targetDoc];
+        // }
+    }
+
+    stopTempMedia = (targetDocField: FieldResult) => {
+        const targetDoc = Cast(targetDocField, Doc, null);
+        if (targetDoc?.type === DocumentType.AUDIO) {
+            if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
+            targetDoc._audioStop = true;
+        } else if (targetDoc?.type === DocumentType.VID) {
+            if (this._mediaTimer && this._mediaTimer[1] === targetDoc) clearTimeout(this._mediaTimer[0]);
+            targetDoc._triggerVideoStop = true;
+        }
+    }
+
+    // No more frames in current doc and next slide is defined, therefore move to next slide 
+    nextSlide = (activeNext: Doc) => {
+        const targetNext = Cast(activeNext.presentationTargetDoc, Doc, null);
+        let nextSelected = this.itemIndex + 1;
+        this.gotoDocument(nextSelected, this.activeItem);
+        for (nextSelected = nextSelected + 1; nextSelected < this.childDocs.length; nextSelected++) {
+            if (!this.childDocs[nextSelected].groupWithUp) {
+                break;
+            } else {
+                console.log("Title: " + this.childDocs[nextSelected].title);
+                this.gotoDocument(nextSelected, this.activeItem, true);
+            }
+        }
+    }
+
+    // Called when the user activates 'next' - to move to the next part of the pres. trail
+    @action
+    next = () => {
+        const activeNext = Cast(this.childDocs[this.itemIndex + 1], Doc, null);
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const lastFrame = Cast(targetDoc?.lastFrame, "number", null);
+        const curFrame = NumCast(targetDoc?._currentFrame);
+        let internalFrames: boolean = false;
+        if (activeItem.presProgressivize || activeItem.zoomProgressivize || targetDoc.scrollProgressivize) internalFrames = true;
+        if (internalFrames && lastFrame !== undefined && curFrame < lastFrame) {
+            // Case 1: There are still other frames and should go through all frames before going to next slide
+            this.nextInternalFrame(targetDoc, activeItem);
+        } else if (this.childDocs[this.itemIndex + 1] !== undefined) {
+            // Case 2: No more frames in current doc and next slide is defined, therefore move to next slide 
+            this.nextSlide(activeNext);
+        } else if (this.childDocs[this.itemIndex + 1] === undefined && (this.layoutDoc.presLoop || this.layoutDoc.presStatus === PresStatus.Edit)) {
+            // Case 3: Last slide and presLoop is toggled ON or it is in Edit mode
+            this.gotoDocument(0, this.activeItem);
+        }
+    }
+
+    // Called when the user activates 'back' - to move to the previous part of the pres. trail
+    @action
+    back = () => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const prevItem = Cast(this.childDocs[Math.max(0, this.itemIndex - 1)], Doc, null);
+        const prevTargetDoc = Cast(prevItem.presentationTargetDoc, Doc, null);
+        const lastFrame = Cast(targetDoc.lastFrame, "number", null);
+        const curFrame = NumCast(targetDoc._currentFrame);
+        let prevSelected = this.itemIndex;
+        // Functionality for group with up
+        let didZoom = activeItem.presMovement;
+        for (; !didZoom && prevSelected > 0 && this.childDocs[prevSelected].groupButton; prevSelected--) {
+            didZoom = this.childDocs[prevSelected].presMovement;
+        }
+        if (lastFrame !== undefined && curFrame >= 1) {
+            // Case 1: There are still other frames and should go through all frames before going to previous slide
+            this.prevKeyframe(targetDoc, activeItem);
+        } else if (activeItem && this.childDocs[this.itemIndex - 1] !== undefined) {
+            // Case 2: There are no other frames so it should go to the previous slide
+            prevSelected = Math.max(0, prevSelected - 1);
+            this.gotoDocument(prevSelected, activeItem);
+            if (NumCast(prevTargetDoc.lastFrame) > 0) prevTargetDoc._currentFrame = NumCast(prevTargetDoc.lastFrame);
+        } else if (this.childDocs[this.itemIndex - 1] === undefined && this.layoutDoc.presLoop) {
+            // Case 3: Pres loop is on so it should go to the last slide
+            this.gotoDocument(this.childDocs.length - 1, activeItem);
+        }
+    }
+
+    //The function that is called when a document is clicked or reached through next or back.
+    //it'll also execute the necessary actions if presentation is playing.
+    public gotoDocument = action((index: number, from?: Doc, group?: boolean) => {
+        Doc.UnBrushAllDocs();
+        if (index >= 0 && index < this.childDocs.length) {
+            this.rootDoc._itemIndex = index;
+            const activeItem: Doc = this.activeItem;
+            const targetDoc: Doc = this.targetDoc;
+            if (from?.mediaStopTriggerList && this.layoutDoc.presStatus !== PresStatus.Edit) {
+                DocListCast(from.mediaStopTriggerList).forEach(this.stopTempMedia);
+            }
+            if (from?.mediaStop === "auto" && this.layoutDoc.presStatus !== PresStatus.Edit) {
+                this.stopTempMedia(from.presentationTargetDoc);
+            }
+            // If next slide is audio / video 'Play automatically' then the next slide should be played
+            if (this.layoutDoc.presStatus !== PresStatus.Edit && (targetDoc.type === DocumentType.AUDIO || targetDoc.type === DocumentType.VID) && (activeItem.mediaStart === "auto")) {
+                this.startTempMedia(targetDoc, activeItem);
+            }
+            if (targetDoc) {
+                targetDoc && runInAction(() => {
+                    if (activeItem.presMovement === PresMovement.Jump) targetDoc.focusSpeed = 0;
+                    else targetDoc.focusSpeed = activeItem.presTransition ? activeItem.presTransition : 500;
+                });
+                setTimeout(() => targetDoc.focusSpeed = 500, this.activeItem.presTransition ? NumCast(this.activeItem.presTransition) + 10 : 510);
+            }
+            if (targetDoc?.lastFrame !== undefined) {
+                targetDoc._currentFrame = 0;
+            }
+            if (!group) this._selectedArray.clear();
+            this.childDocs[index] && this._selectedArray.set(this.childDocs[index], undefined); //Update selected array
+            if (this.layoutDoc._viewType === "stacking" && !group) this.navigateToElement(this.childDocs[index]); //Handles movement to element only when presTrail is list
+            this.onHideDocument(); //Handles hide after/before
+        }
+    });
+
+    _navTimer!: NodeJS.Timeout;
+    navigateToView = (targetDoc: Doc, activeItem: Doc) => {
+        clearTimeout(this._navTimer);
+        const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
+        bestTarget && runInAction(() => {
+            if (bestTarget.type === DocumentType.PDF || bestTarget.type === DocumentType.WEB || bestTarget.type === DocumentType.RTF || bestTarget._viewType === CollectionViewType.Stacking) {
+                bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
+                bestTarget._scrollTop = activeItem.presPinViewScroll;
+            } else if (bestTarget.type === DocumentType.COMPARISON) {
+                bestTarget._clipWidth = activeItem.presPinClipWidth;
+            } else if (bestTarget.type === DocumentType.VID) {
+                bestTarget._currentTimecode = activeItem.presPinTimecode;
+            } else {
+                bestTarget._viewTransition = activeItem.presTransition ? `transform ${activeItem.presTransition}ms` : 'all 0.5s';
+                bestTarget._panX = activeItem.presPinViewX;
+                bestTarget._panY = activeItem.presPinViewY;
+                bestTarget._viewScale = activeItem.presPinViewScale;
+            }
+            this._navTimer = setTimeout(() => bestTarget._viewTransition = undefined, activeItem.presTransition ? NumCast(activeItem.presTransition) + 10 : 510);
+        });
+    }
+
+    /**
+     * This method makes sure that cursor navigates to the element that
+     * has the option open and last in the group. 
+     * Design choice: If the next document is not in presCollection or 
+     * presCollection itself then if there is a presCollection it will add
+     * a new tab. If presCollection is undefined it will open the document
+     * on the right. 
+     */
+    navigateToElement = async (curDoc: Doc) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const srcContext = Cast(targetDoc.context, Doc, null);
+        const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
+        const collectionDocView = presCollection ? DocumentManager.Instance.getDocumentView(presCollection) : undefined;
+        const includesDoc: boolean = DocListCast(presCollection?.data).includes(targetDoc);
+        const tab = Array.from(CollectionDockingView.Instance.tabMap).find(tab => tab.DashDoc === srcContext);
+        this.turnOffEdit();
+        // Handles the setting of presCollection
+        if (includesDoc) {
+            //Case 1: Pres collection should not change as it is already the same
+        } else if (tab !== undefined) {
+            // Case 2: Pres collection should update
+            this.layoutDoc.presCollection = srcContext;
+        }
+        const presStatus = this.rootDoc.presStatus;
+        const selViewCache = Array.from(this._selectedArray.keys());
+        const dragViewCache = Array.from(this._dragArray);
+        const eleViewCache = Array.from(this._eleArray);
+        const self = this;
+        const resetSelection = action(() => {
+            const presDocView = DocumentManager.Instance.getDocumentView(self.rootDoc);
+            if (presDocView) SelectionManager.SelectView(presDocView, false);
+            self.rootDoc.presStatus = presStatus;
+            self._selectedArray.clear();
+            selViewCache.forEach(doc => self._selectedArray.set(doc, undefined));
+            self._dragArray.splice(0, self._dragArray.length, ...dragViewCache);
+            self._eleArray.splice(0, self._eleArray.length, ...eleViewCache);
+        });
+        const openInTab = (doc: Doc, finished?: () => void) => {
+            collectionDocView ? collectionDocView.props.addDocTab(doc, "") : this.props.addDocTab(doc, ":left");
+            this.layoutDoc.presCollection = targetDoc;
+            // this still needs some fixing
+            setTimeout(resetSelection, 500);
+            if (doc !== targetDoc) {
+                setTimeout(finished ?? emptyFunction, 100); /// give it some time to create the targetDoc if we're opening up its context
+            } else {
+                finished?.();
+            }
+        };
+        // If openDocument is selected then it should open the document for the user
+        if (activeItem.openDocument) {
+            LightboxView.SetLightboxDoc(targetDoc);
+        } else if (curDoc.presMovement === PresMovement.Pan && targetDoc) {
+            LightboxView.SetLightboxDoc(undefined);
+            await DocumentManager.Instance.jumpToDocument(targetDoc, false, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right
+        } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) {
+            LightboxView.SetLightboxDoc(undefined);
+            //awaiting jump so that new scale can be found, since jumping is async     
+            await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection); // documents open in new tab instead of on right    
+        }
+        // After navigating to the document, if it is added as a presPinView then it will
+        // adjust the pan and scale to that of the pinView when it was added.
+        if (activeItem.presPinView) {
+            // if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target
+            this.navigateToView(targetDoc, activeItem);
+        }
+        // TODO: Add progressivize for navigating web (storing websites for given frames)
+
+    }
+
+    /**
+     * Uses the viewfinder to progressivize through the different views of a single collection.
+     * @param presTargetDoc: document for which internal zoom is used
+     */
+    zoomProgressivizeNext = (activeItem: Doc) => {
+        const targetDoc: Doc = this.targetDoc;
+        const srcContext = Cast(targetDoc?.context, Doc, null);
+        const docView = DocumentManager.Instance.getDocumentView(targetDoc);
+        const vfLeft = this.checkList(targetDoc, activeItem["viewfinder-left-indexed"]);
+        const vfWidth = this.checkList(targetDoc, activeItem["viewfinder-width-indexed"]);
+        const vfTop = this.checkList(targetDoc, activeItem["viewfinder-top-indexed"]);
+        const vfHeight = this.checkList(targetDoc, activeItem["viewfinder-height-indexed"]);
+        // Case 1: document that is not a Golden Layout tab
+        if (srcContext) {
+            const srcDocView = DocumentManager.Instance.getDocumentView(srcContext);
+            if (srcDocView) {
+                const layoutdoc = Doc.Layout(targetDoc);
+                const panelWidth: number = srcDocView.props.PanelWidth();
+                const panelHeight: number = srcDocView.props.PanelHeight();
+                const newPanX = NumCast(targetDoc.x) + NumCast(layoutdoc._width) / 2;
+                const newPanY = NumCast(targetDoc.y) + NumCast(layoutdoc._height) / 2;
+                const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+                srcContext._panX = newPanX + (vfLeft + (vfWidth / 2));
+                srcContext._panY = newPanY + (vfTop + (vfHeight / 2));
+                srcContext._viewScale = newScale;
+            }
+        }
+        // Case 2: document is the containing collection
+        if (docView && !srcContext) {
+            const panelWidth: number = docView.props.PanelWidth();
+            const panelHeight: number = docView.props.PanelHeight();
+            const newScale = 0.9 * Math.min(Number(panelWidth) / vfWidth, Number(panelHeight) / vfHeight);
+            targetDoc._panX = vfLeft + (vfWidth / 2);
+            targetDoc._panY = vfTop + (vfWidth / 2);
+            targetDoc._viewScale = newScale;
+        }
+        const resize = document.getElementById('resizable');
+        if (resize) {
+            resize.style.width = vfWidth + 'px';
+            resize.style.height = vfHeight + 'px';
+            resize.style.top = vfTop + 'px';
+            resize.style.left = vfLeft + 'px';
+        }
+    }
+
+    /**
+     * For 'Hide Before' and 'Hide After' buttons making sure that
+     * they are hidden each time the presentation is updated.
+     */
+    @action
+    onHideDocument = () => {
+        this.childDocs.forEach((doc, index) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (tagDoc) tagDoc.opacity = 1;
+            const itemIndexes: number[] = this.getAllIndexes(this.tagDocs, tagDoc);
+            const curInd: number = itemIndexes.indexOf(index);
+            if (tagDoc === this.layoutDoc.presCollection) { tagDoc.opacity = 1; }
+            else {
+                if (itemIndexes.length > 1 && curDoc.presHideBefore && curInd !== 0) { }
+                else if (curDoc.presHideBefore) {
+                    if (index > this.itemIndex) {
+                        tagDoc.opacity = 0;
+                    } else if (!curDoc.presHideAfter) {
+                        tagDoc.opacity = 1;
+                    }
+                }
+                if (itemIndexes.length > 1 && curDoc.presHideAfter && curInd !== (itemIndexes.length - 1)) { }
+                else if (curDoc.presHideAfter) {
+                    if (index < this.itemIndex) {
+                        tagDoc.opacity = 0;
+                    } else if (!curDoc.presHideBefore) {
+                        tagDoc.opacity = 1;
+                    }
+                }
+            }
+        });
+    }
+
+
+
+    //The function that starts or resets presentaton functionally, depending on presStatus of the layoutDoc
+    @action
+    startAutoPres = (startSlide: number) => {
+        this.updateCurrentPresentation();
+        let activeItem: Doc = this.activeItem;
+        let targetDoc: Doc = this.targetDoc;
+        let duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
+        const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
+        const load = async () => { // Wrap the loop into an async function for this to work
+            for (var i = startSlide; i < this.childDocs.length; i++) {
+                activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+                targetDoc = Cast(activeItem.presentationTargetDoc, Doc, null);
+                duration = NumCast(activeItem.presDuration) + NumCast(activeItem.presTransition);
+                if (duration < 100) { duration = 2500; }
+                if (NumCast(targetDoc.lastFrame) > 0) {
+                    for (var f = 0; f < NumCast(targetDoc.lastFrame); f++) {
+                        await timer(duration / NumCast(targetDoc.lastFrame));
+                        this.next();
+                    }
+                }
+
+                await timer(duration); this.next(); // then the created Promise can be awaited
+                if (i === this.childDocs.length - 1) {
+                    setTimeout(() => {
+                        clearTimeout(this._presTimer);
+                        if (this.layoutDoc.presStatus === 'auto' && !this.layoutDoc.presLoop) this.layoutDoc.presStatus = PresStatus.Manual;
+                        else if (this.layoutDoc.presLoop) this.startAutoPres(0);
+                    }, duration);
+                }
+            }
+        };
+        this.layoutDoc.presStatus = PresStatus.Autoplay;
+        this.startPresentation(startSlide);
+        this.gotoDocument(startSlide, activeItem);
+        load();
+    }
+
+    @action
+    pauseAutoPres = () => {
+        if (this.layoutDoc.presStatus === PresStatus.Autoplay) {
+            if (this._presTimer) clearTimeout(this._presTimer);
+            this.layoutDoc.presStatus = PresStatus.Manual;
+            this.layoutDoc.presLoop = false;
+            this.childDocs.forEach(this.stopTempMedia);
+        }
+    }
+
+    //The function that resets the presentation by removing every action done by it. It also
+    //stops the presentaton.
+    resetPresentation = () => {
+        this.rootDoc._itemIndex = 0;
+        this.childDocs.map(doc => Cast(doc.presentationTargetDoc, Doc, null)).filter(doc => doc instanceof Doc).forEach(doc => {
+            try {
+                doc.opacity = 1;
+            } catch (e) {
+                console.log("Reset presentation error: ", e);
+            }
+        });
+    }
+
+    @action togglePath = (srcContext: Doc, off?: boolean) => {
+        if (off) {
+            this._pathBoolean = false;
+            srcContext.presPathView = false;
+        } else {
+            runInAction(() => this._pathBoolean = !this._pathBoolean);
+            srcContext.presPathView = this._pathBoolean;
+        }
+    }
+
+    @action toggleExpandMode = () => {
+        runInAction(() => this._expandBoolean = !this._expandBoolean);
+        this.rootDoc.expandBoolean = this._expandBoolean;
+        this.childDocs.forEach((doc) => {
+            doc.presExpandInlineButton = this._expandBoolean;
+        });
+    }
+
+    /**
+     * The function that starts the presentation at the given index, also checking if actions should be applied
+     * directly at start.
+     * @param startIndex: index that the presentation will start at
+     */
+    startPresentation = (startIndex: number) => {
+        this.updateCurrentPresentation();
+        this.childDocs.map(doc => {
+            const tagDoc = doc.presentationTargetDoc as Doc;
+            if (doc.presHideBefore && this.childDocs.indexOf(doc) > startIndex) {
+                tagDoc.opacity = 0;
+            }
+            if (doc.presHideAfter && this.childDocs.indexOf(doc) < startIndex) {
+                tagDoc.opacity = 0;
+            }
+        });
+    }
+
+    /**
+     * The method called to open the presentation as a minimized view
+     */
+    @action
+    updateMinimize = () => {
+        const docView = DocumentManager.Instance.getDocumentView(this.layoutDoc);
+        if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) {
+            console.log("case 1");
+            this.layoutDoc.presStatus = PresStatus.Edit;
+            Doc.RemoveDocFromList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc);
+            CollectionDockingView.AddSplit(this.rootDoc, "right");
+        } else if (this.layoutDoc.context && docView) {
+            console.log("case 2");
+            this.layoutDoc.presStatus = PresStatus.Edit;
+            clearTimeout(this._presTimer);
+            const pt = this.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+            this.rootDoc.x = pt[0] + (this.props.PanelWidth() - 250);
+            this.rootDoc.y = pt[1] + 10;
+            this.rootDoc._height = 35;
+            this.rootDoc._width = 250;
+            docView.props.removeDocument?.(this.layoutDoc);
+            Doc.AddDocToList((Doc.UserDoc().myOverlayDocs as Doc), undefined, this.rootDoc);
+        } else {
+            console.log("case 3");
+            // TODO glr: fix this case
+        }
+    }
+
+    /**
+     * Called when the user changes the view type
+     * Either 'List' (stacking) or 'Slides' (carousel)
+     */
+    // @undoBatch
+    viewChanged = action((e: React.ChangeEvent) => {
+        //@ts-ignore
+        const viewType = e.target.selectedOptions[0].value as CollectionViewType;
+        // pivot field may be set by the user in timeline view (or some other way) -- need to reset it here
+        viewType === CollectionViewType.Stacking && (this.rootDoc._pivotField = undefined);
+        this.rootDoc._viewType = viewType;
+        if (viewType === CollectionViewType.Stacking) this.layoutDoc._gridGap = 0;
+    });
+
+    /**
+     * Called when the user changes the view type
+     * Either 'List' (stacking) or 'Slides' (carousel)
+     */
+    // @undoBatch
+    mediaStopChanged = action((e: React.ChangeEvent) => {
+        const activeItem: Doc = this.activeItem;
+        //@ts-ignore
+        const stopDoc = e.target.selectedOptions[0].value as string;
+        const stopDocIndex: number = Number(stopDoc[0]);
+        activeItem.mediaStopDoc = stopDocIndex;
+        if (this.childDocs[stopDocIndex - 1].mediaStopTriggerList) {
+            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
+            list.push(activeItem);
+            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
+            console.log(list);
+        } else {
+            this.childDocs[stopDocIndex - 1].mediaStopTriggerList = new List<Doc>();
+            const list = DocListCast(this.childDocs[stopDocIndex - 1].mediaStopTriggerList);
+            list.push(activeItem);
+            // this.childDocs[stopDocIndex - 1].mediaStopTriggerList = list;
+            console.log(list);
+        }
+    });
+
+
+    setMovementName = action((movement: any, activeItem: Doc): string => {
+        let output: string = 'none';
+        switch (movement) {
+            case PresMovement.Zoom: output = 'Pan & Zoom'; break; //Pan and zoom
+            case PresMovement.Pan: output = 'Pan'; break; //Pan
+            case PresMovement.Jump: output = 'Jump cut'; break; //Jump Cut
+            case PresMovement.None: output = 'None'; break; //None
+            default: output = 'Zoom'; activeItem.presMovement = 'zoom'; break; //default set as zoom
+        }
+        return output;
+    });
+
+    whenChildContentsActiveChanged = action((isActive: boolean) => this.props.whenChildContentsActiveChanged(this._isChildActive = isActive));
+    // For dragging documents into the presentation trail
+    addDocumentFilter = (docs: Doc[]) => {
+        docs.forEach((doc, i) => {
+            if (doc.presentationTargetDoc) return true;
+            if (doc.type === DocumentType.LABEL) {
+                const audio = Cast(doc.annotationOn, Doc, null);
+                if (audio) {
+                    audio.mediaStart = "manual";
+                    audio.mediaStop = "manual";
+                    audio.presStartTime = NumCast(doc._timecodeToShow /* audioStart */, NumCast(doc._timecodeToShow /* videoStart */));
+                    audio.presEndTime = NumCast(doc._timecodeToHide /* audioEnd */, NumCast(doc._timecodeToHide /* videoEnd */));
+                    audio.presDuration = audio.presStartTime - audio.presEndTime;
+                    TabDocView.PinDoc(audio, { audioRange: true });
+                    setTimeout(() => this.removeDocument(doc), 0);
+                    return false;
+                }
+            } else {
+                if (!doc.aliasOf) {
+                    const original = Doc.MakeAlias(doc);
+                    TabDocView.PinDoc(original);
+                    setTimeout(() => this.removeDocument(doc), 0);
+                    return false;
+                } else {
+                    if (!doc.presentationTargetDoc) doc.title = doc.title + " - Slide";
+                    doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
+                    doc.presMovement = PresMovement.Zoom;
+                    if (this._expandBoolean) doc.presExpandInlineButton = true;
+                }
+            }
+        });
+        return true;
+    }
+    childLayoutTemplate = () => this.rootDoc._viewType !== CollectionViewType.Stacking ? undefined : this.presElement;
+    removeDocument = (doc: Doc) => Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc);
+    getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
+    panelHeight = () => this.props.PanelHeight() - 40;
+    isContentActive = (outsideReaction?: boolean) => ((CurrentUserUtils.SelectedTool === InkTool.None && this.props.layerProvider?.(this.layoutDoc) !== false) &&
+        (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
+
+    /**
+     * For sorting the array so that the order is maintained when it is dropped.
+     */
+    @action
+    sortArray = (): Doc[] => {
+        return this.childDocs.filter(doc => this._selectedArray.has(doc));
+    }
+
+    /**
+     * Method to get the list of selected items in the order in which they have been selected
+     */
+    @computed get listOfSelected() {
+        const list = Array.from(this._selectedArray.keys()).map((doc: Doc, index: any) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (curDoc && curDoc === this.activeItem) return <div key={index} className="selectedList-items"><b>{index + 1}.  {curDoc.title}</b></div>;
+            else if (tagDoc) return <div key={index} className="selectedList-items">{index + 1}.  {curDoc.title}</div>;
+            else if (curDoc) return <div key={index} className="selectedList-items">{index + 1}.  {curDoc.title}</div>;
+        });
+        return list;
+    }
+
+    @action
+    selectPres = () => {
+        const presDocView = DocumentManager.Instance.getDocumentView(this.rootDoc);
+        presDocView && SelectionManager.SelectView(presDocView, false);
+    }
+
+    //Regular click
+    @action
+    selectElement = async (doc: Doc) => {
+        const context = Cast(doc.context, Doc, null);
+        this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem);
+        if (doc.presPinView || doc.presentationTargetDoc === this.layoutDoc.presCollection) setTimeout(() => this.updateCurrentPresentation(context), 0);
+        else this.updateCurrentPresentation(context);
+
+        if (this.activeItem.setPosition &&
+            this.activeItem.y !== undefined &&
+            this.activeItem.x !== undefined &&
+            this.targetDoc.x !== undefined &&
+            this.targetDoc.y !== undefined) {
+            const timer = (ms: number) => new Promise(res => this._presTimer = setTimeout(res, ms));
+            const time = 10;
+            const ydiff = NumCast(this.activeItem.y) - NumCast(this.targetDoc.y);
+            const xdiff = NumCast(this.activeItem.x) - NumCast(this.targetDoc.x);
+
+            for (let i = 0; i < time; i++) {
+                this.targetDoc.x = NumCast(this.targetDoc.x) + xdiff / time;
+                this.targetDoc.y = NumCast(this.targetDoc.y) + ydiff / time;
+                await timer(0.1);
+            }
+        }
+    }
+
+    //Command click
+    @action
+    multiSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
+        if (!this._selectedArray.has(doc)) {
+            this._selectedArray.set(doc, undefined);
+            this._eleArray.push(ref);
+            this._dragArray.push(drag);
+        } else {
+            this._selectedArray.delete(doc);
+            this.removeFromArray(this._eleArray, doc);
+            this.removeFromArray(this._dragArray, doc);
+        }
+        this.selectPres();
+    }
+
+    removeFromArray = (arr: any[], val: any) => {
+        const index: number = arr.indexOf(val);
+        const ret: any[] = arr.splice(index, 1);
+        arr = ret;
+    }
+
+    //Shift click
+    @action
+    shiftSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement) => {
+        this._selectedArray.clear();
+        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        if (this.activeItem) {
+            for (let i = Math.min(this.itemIndex, this.childDocs.indexOf(doc)); i <= Math.max(this.itemIndex, this.childDocs.indexOf(doc)); i++) {
+                this._selectedArray.set(this.childDocs[i], undefined);
+                this._eleArray.push(ref);
+                this._dragArray.push(drag);
+            }
+        }
+        this.selectPres();
+    }
+
+    //regular click
+    @action
+    regularSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean) => {
+        this._selectedArray.clear();
+        this._selectedArray.set(doc, undefined);
+        this._eleArray.splice(0, this._eleArray.length, ref);
+        this._dragArray.splice(0, this._dragArray.length, drag);
+        focus && this.selectElement(doc);
+        this.selectPres();
+    }
+
+    modifierSelect = (doc: Doc, ref: HTMLElement, drag: HTMLElement, focus: boolean, cmdClick: boolean, shiftClick: boolean) => {
+        if (cmdClick) this.multiSelect(doc, ref, drag);
+        else if (shiftClick) this.shiftSelect(doc, ref, drag);
+        else this.regularSelect(doc, ref, drag, focus);
+    }
+
+    static keyEventsWrapper = (e: KeyboardEvent) => {
+        PresBox.Instance.keyEvents(e);
+    }
+
+    // Key for when the presentaiton is active
+    @action
+    keyEvents = (e: KeyboardEvent) => {
+        if (e.target instanceof HTMLInputElement) return;
+        let handled = false;
+        const anchorNode = document.activeElement as HTMLDivElement;
+        if (anchorNode && anchorNode.className?.includes("lm_title")) return;
+        switch (e.key) {
+            case "Backspace":
+                if (this.layoutDoc.presStatus === "edit") {
+                    undoBatch(action(() => {
+                        for (const doc of Array.from(this._selectedArray.keys())) {
+                            this.removeDocument(doc);
+                        }
+                        this._selectedArray.clear();
+                        this._eleArray.length = 0;
+                        this._dragArray.length = 0;
+                    }))();
+                    handled = true;
+                }
+                break;
+            case "Escape":
+                if (CurrentUserUtils.OverlayDocs.includes(this.layoutDoc)) { this.updateMinimize(); }
+                else if (this.layoutDoc.presStatus === "edit") { this._selectedArray.clear(); this._eleArray.length = this._dragArray.length = 0; }
+                else this.layoutDoc.presStatus = "edit";
+                if (this._presTimer) clearTimeout(this._presTimer);
+                handled = true;
+                break;
+            case "Down": case "ArrowDown":
+            case "Right": case "ArrowRight":
+                if (e.shiftKey && this.itemIndex < this.childDocs.length - 1) { // TODO: update to work properly
+                    this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) + 1;
+                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
+                } else {
+                    this.next();
+                    if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
+                }
+                handled = true;
+                break;
+            case "Up": case "ArrowUp":
+            case "Left": case "ArrowLeft":
+                if (e.shiftKey && this.itemIndex !== 0) { // TODO: update to work properly
+                    this.rootDoc._itemIndex = NumCast(this.rootDoc._itemIndex) - 1;
+                    this._selectedArray.set(this.childDocs[this.rootDoc._itemIndex], undefined);
+                } else {
+                    this.back();
+                    if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; }
+                }
+                handled = true;
+                break;
+            case "Spacebar": case " ":
+                if (this.layoutDoc.presStatus === PresStatus.Manual) this.startAutoPres(this.itemIndex);
+                else if (this.layoutDoc.presStatus === PresStatus.Autoplay) if (this._presTimer) clearTimeout(this._presTimer);
+                handled = true;
+                break;
+            case "a":
+                if ((e.metaKey || e.altKey) && this.layoutDoc.presStatus === "edit") {
+                    this._selectedArray.clear();
+                    this.childDocs.forEach(doc => this._selectedArray.set(doc, undefined));
+                    handled = true;
+                }
+            default:
+                break;
+        }
+        if (handled) {
+            e.stopPropagation();
+            e.preventDefault();
+        }
+    }
+
+    /**
+     * 
+     */
+    @action
+    viewPaths = () => {
+        const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
+        if (srcContext) {
+            this.togglePath(srcContext);
+        }
+    }
+
+    getAllIndexes = (arr: Doc[], val: Doc): number[] => {
+        const indexes = [];
+        for (let i = 0; i < arr.length; i++) {
+            arr[i] === val && indexes.push(i);
+        }
+        return indexes;
+    }
+
+    // Adds the index in the pres path graphically
+    @computed get order() {
+        const order: JSX.Element[] = [];
+        const docs: Doc[] = [];
+        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
+        const dv = DocumentManager.Instance.getDocumentView(presCollection);
+        this.childDocs.filter(doc => Cast(doc.presentationTargetDoc, Doc, null)).forEach((doc, index) => {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            const srcContext = Cast(tagDoc.context, Doc, null);
+            const width = NumCast(tagDoc._width) / 10;
+            const height = Math.max(NumCast(tagDoc._height) / 10, 15);
+            const edge = Math.max(width, height);
+            const fontSize = edge * 0.8;
+            const gap = 2;
+            if (presCollection === srcContext) {
+                // Case A: Document is contained within the collection
+                if (docs.includes(tagDoc)) {
+                    const prevOccurances: number = this.getAllIndexes(docs, tagDoc).length;
+                    docs.push(tagDoc);
+                    order.push(
+                        <div className="pathOrder"
+                            key={tagDoc.id + 'pres' + index}
+                            style={{ top: NumCast(tagDoc.y) + (prevOccurances * (edge + gap) - (edge / 2)), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
+                            onClick={() => this.selectElement(doc)}>
+                            <div className="pathOrder-frame">{index + 1}</div>
+                        </div>);
+                } else {
+                    docs.push(tagDoc);
+                    order.push(
+                        <div className="pathOrder"
+                            key={tagDoc.id + 'pres' + index}
+                            style={{ top: NumCast(tagDoc.y) - (edge / 2), left: NumCast(tagDoc.x) - (edge / 2), width: edge, height: edge, fontSize: fontSize }}
+                            onClick={() => this.selectElement(doc)}>
+                            <div className="pathOrder-frame">{index + 1}</div>
+                        </div>);
+                }
+            } else if (doc.presPinView && presCollection === tagDoc && dv) {
+                // Case B: Document is presPinView and is presCollection
+                const scale: number = 1 / NumCast(doc.presPinViewScale);
+                const height: number = dv.props.PanelHeight() * scale;
+                const width: number = dv.props.PanelWidth() * scale;
+                const indWidth = width / 10;
+                const indHeight = Math.max(height / 10, 15);
+                const indEdge = Math.max(indWidth, indHeight);
+                const indFontSize = indEdge * 0.8;
+                const xLoc: number = NumCast(doc.presPinViewX) - (width / 2);
+                const yLoc: number = NumCast(doc.presPinViewY) - (height / 2);
+                docs.push(tagDoc);
+                order.push(
+                    <>
+                        <div className="pathOrder"
+                            key={tagDoc.id + 'pres' + index}
+                            style={{ top: yLoc - (indEdge / 2), left: xLoc - (indEdge / 2), width: indEdge, height: indEdge, fontSize: indFontSize }}
+                            onClick={() => this.selectElement(doc)}
+                        >
+                            <div className="pathOrder-frame">{index + 1}</div>
+                        </div>
+                        <div className="pathOrder-presPinView" style={{ top: yLoc, left: xLoc, width: width, height: height, borderWidth: indEdge / 10 }}></div>
+                    </>);
+            }
+        });
+        return order;
+    }
+
+    /**
+     * Method called for viewing paths which adds a single line with
+     * points at the center of each document added.
+     * Design choice: When this is called it sets _fitToBox as true so the
+     * user can have an overview of all of the documents in the collection.
+     * (Design needed for when documents in presentation trail are in another
+     * collection)
+     */
+    @computed get paths() {
+        let pathPoints = "";
+        const presCollection = Cast(this.rootDoc.presCollection, Doc, null);
+        this.childDocs.forEach((doc, index) => {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            const srcContext = Cast(tagDoc?.context, Doc, null);
+            if (tagDoc && presCollection === srcContext) {
+                const n1x = NumCast(tagDoc.x) + (NumCast(tagDoc._width) / 2);
+                const n1y = NumCast(tagDoc.y) + (NumCast(tagDoc._height) / 2);
+                if (index = 0) pathPoints = n1x + "," + n1y;
+                else pathPoints = pathPoints + " " + n1x + "," + n1y;
+            } else if (doc.presPinView && presCollection === tagDoc) {
+                const n1x = NumCast(doc.presPinViewX);
+                const n1y = NumCast(doc.presPinViewY);
+                if (index = 0) pathPoints = n1x + "," + n1y;
+                else pathPoints = pathPoints + " " + n1x + "," + n1y;
+            }
+        });
+        return (<polyline
+            points={pathPoints}
+            style={{
+                opacity: 1,
+                stroke: "#69a6db",
+                strokeWidth: 5,
+                strokeDasharray: '10 5',
+                boxShadow: '0px 4px 4px rgba(0, 0, 0, 0.25)',
+            }}
+            fill="none"
+            markerStart="url(#markerArrow)"
+            markerMid="url(#markerSquare)"
+            markerEnd="url(#markerSquareFilled)"
+        />);
+    }
+
+    // Converts seconds to ms and updates presTransition
+    setTransitionTime = (number: String, change?: number) => {
+        let timeInMS = Number(number) * 1000;
+        if (change) timeInMS += change;
+        if (timeInMS < 100) timeInMS = 100;
+        if (timeInMS > 10000) timeInMS = 10000;
+        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS);
+    }
+
+    // Converts seconds to ms and updates presDuration
+    setDurationTime = (number: String, change?: number) => {
+        let timeInMS = Number(number) * 1000;
+        if (change) timeInMS += change;
+        if (timeInMS < 100) timeInMS = 100;
+        if (timeInMS > 20000) timeInMS = 20000;
+        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presDuration = timeInMS);
+    }
+
+    /**
+     * When the movement dropdown is changes
+     */
+    @undoBatch
+    updateMovement = action((movement: any, all?: boolean) => {
+        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
+        array.forEach((doc) => {
+            switch (movement) {
+                case PresMovement.Zoom: //Pan and zoom
+                    doc.presMovement = PresMovement.Zoom;
+                    break;
+                case PresMovement.Pan: //Pan
+                    doc.presMovement = PresMovement.Pan;
+                    break;
+                case PresMovement.Jump: //Jump Cut
+                    doc.presJump = true;
+                    doc.presMovement = PresMovement.Jump;
+                    break;
+                case PresMovement.None: default:
+                    doc.presMovement = PresMovement.None;
+                    break;
+            }
+        });
+    });
+
+    @undoBatch
+    @action
+    updateHideBefore = (activeItem: Doc) => {
+        activeItem.presHideBefore = !activeItem.presHideBefore;
+        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideBefore = activeItem.presHideBefore);
+    }
+
+    @undoBatch
+    @action
+    updateHideAfter = (activeItem: Doc) => {
+        activeItem.presHideAfter = !activeItem.presHideAfter;
+        Array.from(this._selectedArray.keys()).forEach((doc) => doc.presHideAfter = activeItem.presHideAfter);
+    }
+
+    @undoBatch
+    @action
+    updateOpenDoc = (activeItem: Doc) => {
+        activeItem.openDocument = !activeItem.openDocument;
+        Array.from(this._selectedArray.keys()).forEach((doc) => {
+            doc.openDocument = activeItem.openDocument;
+        });
+    }
+
+    @undoBatch
+    @action
+    updateEffectDirection = (effect: any, all?: boolean) => {
+        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
+        array.forEach((doc) => {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            switch (effect) {
+                case PresEffect.Left:
+                    tagDoc.presEffectDirection = PresEffect.Left;
+                    break;
+                case PresEffect.Right:
+                    tagDoc.presEffectDirection = PresEffect.Right;
+                    break;
+                case PresEffect.Top:
+                    tagDoc.presEffectDirection = PresEffect.Top;
+                    break;
+                case PresEffect.Bottom:
+                    tagDoc.presEffectDirection = PresEffect.Bottom;
+                    break;
+                case PresEffect.Center: default:
+                    tagDoc.presEffectDirection = PresEffect.Center;
+                    break;
+            }
+        });
+    }
+
+    @undoBatch
+    @action
+    updateEffect = (effect: any, all?: boolean) => {
+        const array: any[] = all ? this.childDocs : Array.from(this._selectedArray.keys());
+        array.forEach((doc) => {
+            const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            switch (effect) {
+                case PresEffect.Bounce:
+                    tagDoc.presEffect = PresEffect.Bounce;
+                    break;
+                case PresEffect.Fade:
+                    tagDoc.presEffect = PresEffect.Fade;
+                    break;
+                case PresEffect.Flip:
+                    tagDoc.presEffect = PresEffect.Flip;
+                    break;
+                case PresEffect.Roll:
+                    tagDoc.presEffect = PresEffect.Roll;
+                    break;
+                case PresEffect.Rotate:
+                    tagDoc.presEffect = PresEffect.Rotate;
+                    break;
+                case PresEffect.None: default:
+                    tagDoc.presEffect = PresEffect.None;
+                    break;
+            }
+        });
+    }
+
+    _batch: UndoManager.Batch | undefined = undefined;
+
+    @computed get transitionDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const type = targetDoc.type;
+        const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection);
+        const isPinWithView: boolean = BoolCast(activeItem.presPinView);
+        if (activeItem && targetDoc) {
+            const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5;
+            let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2;
+            if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration);
+            const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None';
+            activeItem.presMovement = activeItem.presMovement ? activeItem.presMovement : 'Zoom';
+            return (
+                <div className={`presBox-ribbon ${this.transitionTools && this.layoutDoc.presStatus === PresStatus.Edit ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = false; this.openEffectDropdown = false; })}>
+                    <div className="ribbon-box">
+                        Movement
+                        {isPresCollection || (isPresCollection && isPinWithView) ?
+                            <div className="ribbon-property" style={{ marginLeft: 0, height: 25, textAlign: 'left', paddingLeft: 5, paddingRight: 5, fontSize: 10 }}>
+                                {this.scrollable ? "Scroll to pinned view" : !isPinWithView ? "No movement" : "Pan & Zoom to pinned view"}
+                            </div>
+                            :
+                            <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openMovementDropdown = !this.openMovementDropdown; })} style={{ borderBottomLeftRadius: this.openMovementDropdown ? 0 : 5, border: this.openMovementDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
+                                {this.setMovementName(activeItem.presMovement, activeItem)}
+                                <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openMovementDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} />
+                                <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} onPointerDown={e => e.stopPropagation()} style={{ display: this.openMovementDropdown ? "grid" : "none" }}>
+                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.None ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.None)}>None</div>
+                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Zoom ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Zoom)}>Pan {"&"} Zoom</div>
+                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Pan ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Pan)}>Pan</div>
+                                    <div className={`presBox-dropdownOption ${activeItem.presMovement === PresMovement.Jump ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateMovement(PresMovement.Jump)}>Jump cut</div>
+                                </div>
+                            </div>
+                        }
+                        <div className="ribbon-doubleButton" style={{ display: activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "inline-flex" : "none" }}>
+                            <div className="presBox-subheading">Movement Speed</div>
+                            <div className="ribbon-property">
+                                <input className="presBox-input"
+                                    type="number" value={transitionSpeed}
+                                    onChange={action((e) => this.setTransitionTime(e.target.value))} /> s
+                            </div>
+                            <div className="ribbon-propertyUpDown">
+                                <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), 1000))}>
+                                    <FontAwesomeIcon icon={"caret-up"} />
+                                </div>
+                                <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setTransitionTime(String(transitionSpeed), -1000))}>
+                                    <FontAwesomeIcon icon={"caret-down"} />
+                                </div>
+                            </div>
+                        </div>
+                        <input type="range" step="0.1" min="0.1" max="10" value={transitionSpeed}
+                            className={`toolbar-slider ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}
+                            id="toolbar-slider"
+                            onPointerDown={() => this._batch = UndoManager.StartBatch("presTransition")}
+                            onPointerUp={() => this._batch?.end()}
+                            onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+                                e.stopPropagation();
+                                this.setTransitionTime(e.target.value);
+                            }} />
+                        <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
+                            <div className="slider-text">Fast</div>
+                            <div className="slider-text">Medium</div>
+                            <div className="slider-text">Slow</div>
+                        </div>
+                    </div>
+                    <div className="ribbon-box">
+                        Visibility {"&"} Duration
+                        <div className="ribbon-doubleButton">
+                            {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide before presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideBefore ? "active" : ""}`} onClick={() => this.updateHideBefore(activeItem)}>Hide before</div></Tooltip>}
+                            {isPresCollection ? (null) : <Tooltip title={<><div className="dash-tooltip">{"Hide after presented"}</div></>}><div className={`ribbon-toggle ${activeItem.presHideAfter ? "active" : ""}`} onClick={() => this.updateHideAfter(activeItem)}>Hide after</div></Tooltip>}
+                            <Tooltip title={<><div className="dash-tooltip">{"Open in lightbox view"}</div></>}><div className="ribbon-toggle" style={{ backgroundColor: activeItem.openDocument ? Colors.LIGHT_BLUE : "" }} onClick={() => this.updateOpenDoc(activeItem)}>Lightbox</div></Tooltip>
+                        </div>
+                        {(type === DocumentType.AUDIO || type === DocumentType.VID) ? (null) : <>
+                            <div className="ribbon-doubleButton" >
+                                <div className="presBox-subheading">Slide Duration</div>
+                                <div className="ribbon-property">
+                                    <input className="presBox-input"
+                                        type="number" value={duration}
+                                        onChange={action((e) => this.setDurationTime(e.target.value))} /> s
+                            </div>
+                                <div className="ribbon-propertyUpDown">
+                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), 1000))}>
+                                        <FontAwesomeIcon icon={"caret-up"} />
+                                    </div>
+                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setDurationTime(String(duration), -1000))}>
+                                        <FontAwesomeIcon icon={"caret-down"} />
+                                    </div>
+                                </div>
+                            </div>
+                            <input type="range" step="0.1" min="0.1" max="20" value={duration}
+                                style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "block" }}
+                                className={"toolbar-slider"} id="duration-slider"
+                                onPointerDown={() => { this._batch = UndoManager.StartBatch("presDuration"); }}
+                                onPointerUp={() => { if (this._batch) this._batch.end(); }}
+                                onChange={(e: React.ChangeEvent<HTMLInputElement>) => { e.stopPropagation(); this.setDurationTime(e.target.value); }}
+                            />
+                            <div className={"slider-headers"} style={{ display: targetDoc.type === DocumentType.AUDIO ? "none" : "grid" }}>
+                                <div className="slider-text">Short</div>
+                                <div className="slider-text">Medium</div>
+                                <div className="slider-text">Long</div>
+                            </div>
+                        </>}
+                    </div>
+                    {isPresCollection ? (null) : <div className="ribbon-box">
+                        Effects
+                        <div className="presBox-dropdown" onClick={action(e => { e.stopPropagation(); this.openEffectDropdown = !this.openEffectDropdown; })} style={{ borderBottomLeftRadius: this.openEffectDropdown ? 0 : 5, border: this.openEffectDropdown ? `solid 2px ${Colors.MEDIUM_BLUE}` : 'solid 1px black' }}>
+                            {effect}
+                            <FontAwesomeIcon className='presBox-dropdownIcon' style={{ gridColumn: 2, color: this.openEffectDropdown ? Colors.MEDIUM_BLUE : 'black' }} icon={"angle-down"} />
+                            <div className={'presBox-dropdownOptions'} id={'presBoxMovementDropdown'} style={{ display: this.openEffectDropdown ? "grid" : "none" }} onPointerDown={e => e.stopPropagation()}>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.None || !targetDoc.presEffect ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.None)}>None</div>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Fade ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Fade)}>Fade In</div>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Flip ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Flip)}>Flip</div>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Rotate ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Rotate)}>Rotate</div>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Bounce ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Bounce)}>Bounce</div>
+                                <div className={`presBox-dropdownOption ${targetDoc.presEffect === PresEffect.Roll ? "active" : ""}`} onPointerDown={e => e.stopPropagation()} onClick={() => this.updateEffect(PresEffect.Roll)}>Roll</div>
+                            </div>
+                        </div>
+                        <div className="ribbon-doubleButton" style={{ display: effect === 'None' ? "none" : "inline-flex" }}>
+                            <div className="presBox-subheading" >Effect direction</div>
+                            <div className="ribbon-property">
+                                {this.effectDirection}
+                            </div>
+                        </div>
+                        <div className="effectDirection" style={{ display: effect === 'None' ? "none" : "grid", width: 40 }}>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from left"}</div></>}><div style={{ gridColumn: 1, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Left ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Left)}><FontAwesomeIcon icon={"angle-right"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from right"}</div></>}><div style={{ gridColumn: 3, gridRow: 2, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Right ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Right)}><FontAwesomeIcon icon={"angle-left"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from top"}</div></>}><div style={{ gridColumn: 2, gridRow: 1, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Top ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Top)}><FontAwesomeIcon icon={"angle-down"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from bottom"}</div></>}><div style={{ gridColumn: 2, gridRow: 3, justifySelf: 'center', color: targetDoc.presEffectDirection === PresEffect.Bottom ? Colors.LIGHT_BLUE : "black", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Bottom)}><FontAwesomeIcon icon={"angle-up"} /></div></Tooltip>
+                            <Tooltip title={<><div className="dash-tooltip">{"Enter from center"}</div></>}><div style={{ gridColumn: 2, gridRow: 2, width: 10, height: 10, alignSelf: 'center', justifySelf: 'center', border: targetDoc.presEffectDirection === PresEffect.Center || !targetDoc.presEffectDirection ? `solid 2px ${Colors.LIGHT_BLUE}` : "solid 2px black", borderRadius: "100%", cursor: "pointer" }} onClick={() => this.updateEffectDirection(PresEffect.Center)}></div></Tooltip>
+                        </div>
+                    </div>}
+                    <div className="ribbon-final-box">
+                        <div className="ribbon-final-button-hidden" onClick={() => this.applyTo(this.childDocs)}>
+                            Apply to all
+                        </div>
+                    </div>
+                </div >
+            );
+        }
+    }
+
+    @computed get effectDirection(): string {
+        let effect = '';
+        switch (this.targetDoc.presEffectDirection) {
+            case 'left': effect = "Enter from left"; break;
+            case 'right': effect = "Enter from right"; break;
+            case 'top': effect = "Enter from top"; break;
+            case 'bottom': effect = "Enter from bottom"; break;
+            default: effect = "Enter from center"; break;
+        }
+        return effect;
+    }
+
+    @undoBatch
+    @action
+    applyTo = (array: Doc[]) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        this.updateMovement(activeItem.presMovement, true);
+        this.updateEffect(targetDoc.presEffect, true);
+        this.updateEffectDirection(targetDoc.presEffectDirection, true);
+        array.forEach((doc) => {
+            const curDoc = Cast(doc, Doc, null);
+            const tagDoc = Cast(curDoc.presentationTargetDoc, Doc, null);
+            if (tagDoc && targetDoc) {
+                curDoc.presTransition = activeItem.presTransition;
+                curDoc.presDuration = activeItem.presDuration;
+                curDoc.presHideBefore = activeItem.presHideBefore;
+                curDoc.presHideAfter = activeItem.presHideAfter;
+            }
+        });
+    }
+
+    @computed get presPinViewOptionsDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: "auto", width: 16, filter: 'invert(1)' }} />;
+        return (
+            <>
+                {this.panable || this.scrollable || this.targetDoc.type === DocumentType.COMPARISON ? 'Pinned view' : (null)}
+                <div className="ribbon-doubleButton">
+                    <Tooltip title={<><div className="dash-tooltip">{activeItem.presPinView ? "Turn off pin with view" : "Turn on pin with view"}</div></>}><div className="ribbon-toggle" style={{ width: 20, padding: 0, backgroundColor: activeItem.presPinView ? Colors.LIGHT_BLUE : "" }}
+                        onClick={() => {
+                            activeItem.presPinView = !activeItem.presPinView;
+                            targetDoc.presPinView = activeItem.presPinView;
+                            if (activeItem.presPinView) {
+                                if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
+                                    const scroll = targetDoc._scrollTop;
+                                    activeItem.presPinView = true;
+                                    activeItem.presPinViewScroll = scroll;
+                                } else if (targetDoc.type === DocumentType.VID) {
+                                    activeItem.presPinTimecode = targetDoc._currentTimecode;
+                                } else if ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG) {
+                                    const x = targetDoc._panX;
+                                    const y = targetDoc._panY;
+                                    const scale = targetDoc._viewScale;
+                                    activeItem.presPinView = true;
+                                    activeItem.presPinViewX = x;
+                                    activeItem.presPinViewY = y;
+                                    activeItem.presPinViewScale = scale;
+                                } else if (targetDoc.type === DocumentType.COMPARISON) {
+                                    const width = targetDoc._clipWidth;
+                                    activeItem.presPinClipWidth = width;
+                                    activeItem.presPinView = true;
+                                }
+                            }
+                        }}>{presPinWithViewIcon}</div></Tooltip>
+                    {activeItem.presPinView ? <Tooltip title={<><div className="dash-tooltip">{"Update the pinned view with the view of the selected document"}</div></>}><div className="ribbon-button"
+                        onClick={() => {
+                            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
+                                const scroll = targetDoc._scrollTop;
+                                activeItem.presPinViewScroll = scroll;
+                            } else if (targetDoc.type === DocumentType.VID) {
+                                activeItem.presPinTimecode = targetDoc._currentTimecode;
+                            } else if (targetDoc.type === DocumentType.COMPARISON) {
+                                const clipWidth = targetDoc._clipWidth;
+                                activeItem.presPinClipWidth = clipWidth;
+                            } else {
+                                const x = targetDoc._panX;
+                                const y = targetDoc._panY;
+                                const scale = targetDoc._viewScale;
+                                activeItem.presPinViewX = x;
+                                activeItem.presPinViewY = y;
+                                activeItem.presPinViewScale = scale;
+                            }
+                        }}>Update</div></Tooltip> : (null)}
+                </div>
+            </>
+        );
+    }
+
+    @computed get panOptionsDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        return (
+            <>
+                {this.panable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
+                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+                        <div className="presBox-subheading">Pan X</div>
+                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+                            <input className="presBox-input"
+                                style={{ textAlign: 'left', width: 50 }}
+                                type="number" value={NumCast(activeItem.presPinViewX)}
+                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewX = Number(val); })} />
+                        </div>
+                    </div>
+                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+                        <div className="presBox-subheading">Pan Y</div>
+                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+                            <input className="presBox-input"
+                                style={{ textAlign: 'left', width: 50 }}
+                                type="number" value={NumCast(activeItem.presPinViewY)}
+                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewY = Number(val); })} />
+                        </div>
+                    </div>
+                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+                        <div className="presBox-subheading">Scale</div>
+                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+                            <input className="presBox-input"
+                                style={{ textAlign: 'left', width: 50 }}
+                                type="number" value={NumCast(activeItem.presPinViewScale)}
+                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScale = Number(val); })} />
+                        </div>
+                    </div>
+                </div> : (null)}
+            </>
+        );
+    }
+
+    @computed get scrollOptionsDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        return (
+            <>
+                {this.scrollable ? <div style={{ display: activeItem.presPinView ? "block" : "none" }}>
+                    <div className="ribbon-doubleButton" style={{ marginRight: 10 }}>
+                        <div className="presBox-subheading">Scroll</div>
+                        <div className="ribbon-property" style={{ paddingRight: 0, paddingLeft: 0 }}>
+                            <input className="presBox-input"
+                                style={{ textAlign: 'left', width: 50 }}
+                                type="number" value={NumCast(activeItem.presPinViewScroll)}
+                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { const val = e.target.value; activeItem.presPinViewScroll = Number(val); })} />
+                        </div>
+                    </div>
+                </div> : (null)}
+            </>
+        );
+    }
+
+    @computed get mediaStopSlides() {
+        const activeItem: Doc = this.activeItem;
+        const list = this.childDocs.map((doc, i) => {
+            if (i > this.itemIndex) {
+                return (
+                    <option>{i + 1}. {doc.title}</option>
+                );
+            }
+        });
+        return (
+            list
+        );
+    }
+
+    @computed get mediaOptionsDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const duration = Math.round(NumCast(activeItem[`${Doc.LayoutFieldKey(activeItem)}-duration`]) * 10);
+        const mediaStopDocInd: number = NumCast(activeItem.mediaStopDoc);
+        const mediaStopDocStr: string = mediaStopDocInd ? mediaStopDocInd + ". " + this.childDocs[mediaStopDocInd - 1].title : "";
+        if (activeItem && targetDoc) {
+            return (
+                <div>
+                    <div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                        <div>
+                            <div className="ribbon-box">
+                                Start {"&"} End Time
+                                <div className={"slider-headers"}>
+                                    <div className="slider-block" >
+                                        <div className="slider-text" style={{ fontWeight: 500 }}>
+                                            Start time (s)
+                                        </div>
+                                        <div id={"startTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
+                                            <input className="presBox-input"
+                                                style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
+                                                type="number" value={NumCast(activeItem.presStartTime)}
+                                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presStartTime = Number(e.target.value); })}
+                                            />
+                                        </div>
+                                    </div>
+                                    <div className="slider-block">
+                                        <div className="slider-text" style={{ fontWeight: 500 }}>
+                                            Duration (s)
+                                        </div>
+                                        <div className="slider-number" style={{ backgroundColor: Colors.LIGHT_BLUE }}>
+                                            {Math.round((NumCast(activeItem.presEndTime) - NumCast(activeItem.presStartTime)) * 10) / 10}
+                                        </div>
+                                    </div>
+                                    <div className="slider-block">
+                                        <div className="slider-text" style={{ fontWeight: 500 }}>
+                                            End time (s)
+                                        </div>
+                                        <div id={"endTime"} className="slider-number" style={{ backgroundColor: Colors.LIGHT_GRAY }}>
+                                            <input className="presBox-input"
+                                                style={{ textAlign: 'center', width: 30, height: 15, fontSize: 10 }}
+                                                type="number" value={NumCast(activeItem.presEndTime)}
+                                                onChange={action((e: React.ChangeEvent<HTMLInputElement>) => { activeItem.presEndTime = Number(e.target.value); })}
+                                            />
+                                        </div>
+                                    </div>
+                                </div>
+                                <div className="multiThumb-slider">
+                                    <input type="range" step="0.1" min="0" max={duration / 10} value={NumCast(activeItem.presEndTime)}
+                                        style={{ gridColumn: 1, gridRow: 1 }}
+                                        className={`toolbar-slider ${"end"}`}
+                                        id="toolbar-slider"
+                                        onPointerDown={() => {
+                                            this._batch = UndoManager.StartBatch("presEndTime");
+                                            const endBlock = document.getElementById("endTime");
+                                            if (endBlock) {
+                                                endBlock.style.color = Colors.LIGHT_GRAY;
+                                                endBlock.style.backgroundColor = Colors.MEDIUM_BLUE;
+                                            }
+                                        }}
+                                        onPointerUp={() => {
+                                            this._batch?.end();
+                                            const endBlock = document.getElementById("endTime");
+                                            if (endBlock) {
+                                                endBlock.style.color = Colors.BLACK;
+                                                endBlock.style.backgroundColor = Colors.LIGHT_GRAY;
+                                            }
+                                        }}
+                                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+                                            e.stopPropagation();
+                                            activeItem.presEndTime = Number(e.target.value);
+                                        }} />
+                                    <input type="range" step="0.1" min="0" max={duration / 10} value={NumCast(activeItem.presStartTime)}
+                                        style={{ gridColumn: 1, gridRow: 1 }}
+                                        className={`toolbar-slider ${"start"}`}
+                                        id="toolbar-slider"
+                                        onPointerDown={() => {
+                                            this._batch = UndoManager.StartBatch("presStartTime");
+                                            const startBlock = document.getElementById("startTime");
+                                            if (startBlock) {
+                                                startBlock.style.color = Colors.LIGHT_GRAY;
+                                                startBlock.style.backgroundColor = Colors.MEDIUM_BLUE;
+                                            }
+                                        }}
+                                        onPointerUp={() => {
+                                            this._batch?.end();
+                                            const startBlock = document.getElementById("startTime");
+                                            if (startBlock) {
+                                                startBlock.style.color = Colors.BLACK;
+                                                startBlock.style.backgroundColor = Colors.LIGHT_GRAY;
+                                            }
+                                        }}
+                                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
+                                            e.stopPropagation();
+                                            activeItem.presStartTime = Number(e.target.value);
+                                        }} />
+                                </div>
+                                <div className={`slider-headers ${activeItem.presMovement === PresMovement.Pan || activeItem.presMovement === PresMovement.Zoom ? "" : "none"}`}>
+                                    <div className="slider-text">0 s</div>
+                                    <div className="slider-text"></div>
+                                    <div className="slider-text">{duration / 10} s</div>
+                                </div>
+                            </div>
+                            <div className="ribbon-final-box">
+                                Playback
+                                <div className="presBox-subheading">Start playing:</div>
+                                <div className="presBox-radioButtons">
+                                    <div className="checkbox-container">
+                                        <input className="presBox-checkbox"
+                                            type="checkbox"
+                                            onChange={() => activeItem.mediaStart = "manual"}
+                                            checked={activeItem.mediaStart === "manual"}
+                                        />
+                                        <div>On click</div>
+                                    </div>
+                                    <div className="checkbox-container">
+                                        <input className="presBox-checkbox"
+                                            type="checkbox"
+                                            onChange={() => activeItem.mediaStart = "auto"}
+                                            checked={activeItem.mediaStart === "auto"}
+                                        />
+                                        <div>Automatically</div>
+                                    </div>
+                                </div>
+                                <div className="presBox-subheading">Stop playing:</div>
+                                <div className="presBox-radioButtons">
+                                    <div className="checkbox-container">
+                                        <input className="presBox-checkbox"
+                                            type="checkbox"
+                                            onChange={() => activeItem.mediaStop = "manual"}
+                                            checked={activeItem.mediaStop === "manual"}
+                                        />
+                                        <div>At audio end time</div>
+                                    </div>
+                                    <div className="checkbox-container">
+                                        <input className="presBox-checkbox"
+                                            type="checkbox"
+                                            onChange={() => activeItem.mediaStop = "auto"}
+                                            checked={activeItem.mediaStop === "auto"}
+                                        />
+                                        <div>On slide change</div>
+                                    </div>
+                                    {/* <div className="checkbox-container">
+                                    <input className="presBox-checkbox"
+                                        type="checkbox"
+                                        onChange={() => activeItem.mediaStop = "afterSlide"}
+                                        checked={activeItem.mediaStop === "afterSlide"}
+                                    />
+                                    <div className="checkbox-dropdown">
+                                        After chosen slide
+                                        <select className="presBox-viewPicker"
+                                            style={{ opacity: activeItem.mediaStop === "afterSlide" && this.itemIndex !== this.childDocs.length - 1 ? 1 : 0.3 }}
+                                            onPointerDown={e => e.stopPropagation()}
+                                            onChange={this.mediaStopChanged}
+                                            value={mediaStopDocStr}>
+                                            {this.mediaStopSlides}
+                                        </select>
+                                    </div>
+                                </div> */}
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div >
+            );
+        }
+    }
+
+    @computed get newDocumentToolbarDropdown() {
+        return (
+            <div>
+                <div className={'presBox-toolbar-dropdown'} style={{ display: this.newDocumentTools && this.layoutDoc.presStatus === "edit" ? "inline-flex" : "none" }} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                    <div className="layout-container" style={{ height: 'max-content' }}>
+                        <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'blank'; this.createNewSlide(this.layout); })} />
+                        <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'title'; this.createNewSlide(this.layout); })}>
+                            <div className="title">Title</div>
+                            <div className="subtitle">Subtitle</div>
+                        </div>
+                        <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'header'; this.createNewSlide(this.layout); })}>
+                            <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
+                        </div>
+                        <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => { this.layout = 'content'; this.createNewSlide(this.layout); })}>
+                            <div className="title" style={{ alignSelf: 'center' }}>Title</div>
+                            <div className="content">Text goes here</div>
+                        </div>
+                    </div>
+                </div>
+            </div >
+        );
+    }
+
+    @observable openLayouts: boolean = false;
+    @observable addFreeform: boolean = true;
+    @observable layout: string = "";
+    @observable title: string = "";
+
+    @computed get newDocumentDropdown() {
+        return (
+            <div>
+                <div className={"presBox-ribbon"} onClick={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                    <div className="ribbon-box">
+                        Slide Title: <br></br>
+                        <input className="ribbon-textInput" placeholder="..." type="text" name="fname"
+                            onChange={(e) => {
+                                e.stopPropagation();
+                                e.preventDefault();
+                                runInAction(() => this.title = e.target.value);
+                            }}>
+                        </input>
+                    </div>
+                    <div className="ribbon-box">
+                        Choose type:
+                        <div className="ribbon-doubleButton">
+                            <div title="Text" className={'ribbon-toggle'} style={{ background: this.addFreeform ? "" : Colors.LIGHT_BLUE }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Text</div>
+                            <div title="Freeform" className={'ribbon-toggle'} style={{ background: this.addFreeform ? Colors.LIGHT_BLUE : "" }} onClick={action(() => this.addFreeform = !this.addFreeform)}>Freeform</div>
+                        </div>
+                    </div>
+                    <div className="ribbon-box" style={{ display: this.addFreeform ? "grid" : "none" }}>
+                        Preset layouts:
+                        <div className="layout-container" style={{ height: this.openLayouts ? 'max-content' : '75px' }}>
+                            <div className="layout" style={{ border: this.layout === 'blank' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'blank')} />
+                            <div className="layout" style={{ border: this.layout === 'title' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'title')}>
+                                <div className="title">Title</div>
+                                <div className="subtitle">Subtitle</div>
+                            </div>
+                            <div className="layout" style={{ border: this.layout === 'header' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'header')}>
+                                <div className="title" style={{ alignSelf: 'center', fontSize: 10 }}>Section header</div>
+                            </div>
+                            <div className="layout" style={{ border: this.layout === 'content' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'content')}>
+                                <div className="title" style={{ alignSelf: 'center' }}>Title</div>
+                                <div className="content">Text goes here</div>
+                            </div>
+                            <div className="layout" style={{ border: this.layout === 'twoColumns' ? `solid 2px ${Colors.MEDIUM_BLUE}` : '' }} onClick={action(() => this.layout = 'twoColumns')}>
+                                <div className="title" style={{ alignSelf: 'center', gridColumn: '1/3' }}>Title</div>
+                                <div className="content" style={{ gridColumn: 1, gridRow: 2 }}>Column one text</div>
+                                <div className="content" style={{ gridColumn: 2, gridRow: 2 }}>Column two text</div>
+                            </div>
+                        </div>
+                        <div className="open-layout" onClick={action(() => this.openLayouts = !this.openLayouts)}>
+                            <FontAwesomeIcon style={{ transition: 'all 0.3s', transform: this.openLayouts ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"caret-down"} size={"lg"} />
+                        </div>
+                    </div>
+                    <div className="ribbon-final-box">
+                        <div className={this.title !== "" && (this.addFreeform && this.layout !== "" || !this.addFreeform) ? "ribbon-final-button-hidden" : "ribbon-final-button"} onClick={() => this.createNewSlide(this.layout, this.title, this.addFreeform)}>
+                            Create New Slide
+                        </div>
+                    </div>
+                </div>
+            </div >
+        );
+    }
+
+    createNewSlide = (layout?: string, title?: string, freeform?: boolean) => {
+        let doc = undefined;
+        if (layout) doc = this.createTemplate(layout);
+        if (freeform && layout) doc = this.createTemplate(layout, title);
+        if (!freeform && !layout) doc = Docs.Create.TextDocument("", { _nativeWidth: 400, _width: 225, title: title });
+        if (doc) {
+            const presCollection = Cast(this.layoutDoc.presCollection, Doc, null);
+            const data = Cast(presCollection?.data, listSpec(Doc));
+            const presData = Cast(this.rootDoc.data, listSpec(Doc));
+            if (data && presData) {
+                data.push(doc);
+                TabDocView.PinDoc(doc);
+                this.gotoDocument(this.childDocs.length, this.activeItem);
+            } else {
+                this.props.addDocTab(doc, "add:right");
+            }
+        }
+    }
+
+    createTemplate = (layout: string, input?: string) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        let x = 0;
+        let y = 0;
+        if (activeItem && targetDoc) {
+            x = NumCast(targetDoc.x);
+            y = NumCast(targetDoc.y) + NumCast(targetDoc._height) + 20;
+        }
+        let doc = undefined;
+        const title = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 58, _fontSize: "24pt", });
+        const subtitle = Docs.Create.TextDocument("Click to change subtitle", { title: "Slide subtitle", _width: 380, _height: 50, x: 10, y: 118, _fontSize: "16pt" });
+        const header = Docs.Create.TextDocument("Click to change header", { title: "Slide header", _width: 380, _height: 65, x: 10, y: 80, _fontSize: "20pt" });
+        const contentTitle = Docs.Create.TextDocument("Click to change title", { title: "Slide title", _width: 380, _height: 60, x: 10, y: 10, _fontSize: "24pt" });
+        const content = Docs.Create.TextDocument("Click to change text", { title: "Slide text", _width: 380, _height: 145, x: 10, y: 70, _fontSize: "14pt" });
+        const content1 = Docs.Create.TextDocument("Click to change text", { title: "Column 1", _width: 185, _height: 140, x: 10, y: 80, _fontSize: "14pt" });
+        const content2 = Docs.Create.TextDocument("Click to change text", { title: "Column 2", _width: 185, _height: 140, x: 205, y: 80, _fontSize: "14pt" });
+        switch (layout) {
+            case 'blank':
+                doc = Docs.Create.FreeformDocument([], { title: input ? input : "Blank slide", _width: 400, _height: 225, x: x, y: y });
+                break;
+            case 'title':
+                doc = Docs.Create.FreeformDocument([title, subtitle], { title: input ? input : "Title slide", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                break;
+            case 'header':
+                doc = Docs.Create.FreeformDocument([header], { title: input ? input : "Section header", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                break;
+            case 'content':
+                doc = Docs.Create.FreeformDocument([contentTitle, content], { title: input ? input : "Title and content", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                break;
+            case 'twoColumns':
+                doc = Docs.Create.FreeformDocument([contentTitle, content1, content2], { title: input ? input : "Title and two columns", _width: 400, _height: 225, _fitToBox: true, x: x, y: y });
+                break;
+            default:
+                break;
+        }
+        return doc;
+    }
+
+    // Dropdown that appears when the user wants to begin presenting (either minimize or sidebar view)
+    @computed get presentDropdown() {
+        return (
+            <div className={`dropdown-play ${this.presentTools ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.updateMinimize(); this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
+                    Mini-player
+                </div>
+                <div className="dropdown-play-button" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "manual"; this.turnOffEdit(true); this.gotoDocument(this.itemIndex, this.activeItem); }))}>
+                    Sidebar player
+                </div>
+            </div>
+        );
+    }
+
+    // Case in which the document has keyframes to navigate to next key frame
+    @action
+    nextKeyframe = (tagDoc: Doc, curDoc: Doc): void => {
+        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
+        const currentFrame = Cast(tagDoc._currentFrame, "number", null);
+        if (currentFrame === undefined) {
+            tagDoc._currentFrame = 0;
+            // CollectionFreeFormDocumentView.setupScroll(tagDoc, 0);
+            // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+        }
+        // if (tagDoc.editScrollProgressivize) CollectionFreeFormDocumentView.updateScrollframe(tagDoc, currentFrame);
+        CollectionFreeFormDocumentView.updateKeyframe(childDocs, currentFrame || 0, tagDoc);
+        tagDoc._currentFrame = Math.max(0, (currentFrame || 0) + 1);
+        tagDoc.lastFrame = Math.max(NumCast(tagDoc._currentFrame), NumCast(tagDoc.lastFrame));
+    }
+
+    @action
+    prevKeyframe = (tagDoc: Doc, actItem: Doc): void => {
+        const childDocs = DocListCast(tagDoc[Doc.LayoutFieldKey(tagDoc)]);
+        const currentFrame = Cast(tagDoc._currentFrame, "number", null);
+        if (currentFrame === undefined) {
+            tagDoc._currentFrame = 0;
+            // CollectionFreeFormDocumentView.setupKeyframes(childDocs, 0);
+        }
+        CollectionFreeFormDocumentView.gotoKeyframe(childDocs.slice());
+        tagDoc._currentFrame = Math.max(0, (currentFrame || 0) - 1);
+    }
+
+    /**
+     * Returns the collection type as a string for headers
+     */
+    @computed get stringType(): string {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        let type: string = '';
+        if (activeItem) {
+            switch (targetDoc.type) {
+                case DocumentType.PDF: type = "PDF"; break;
+                case DocumentType.RTF: type = "Text node"; break;
+                case DocumentType.COL: type = "Collection"; break;
+                case DocumentType.AUDIO: type = "Audio"; break;
+                case DocumentType.VID: type = "Video"; break;
+                case DocumentType.IMG: type = "Image"; break;
+                case DocumentType.WEB: type = "Web page"; break;
+                default: type = "Other node"; break;
+            }
+        }
+        return type;
+    }
+
+    @observable private openActiveColorPicker: boolean = false;
+    @observable private openViewedColorPicker: boolean = false;
+
+
+
+    @computed get progressivizeDropdown() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        if (activeItem && targetDoc) {
+            const activeFontColor = targetDoc["pres-text-color"] ? StrCast(targetDoc["pres-text-color"]) : "Black";
+            const viewedFontColor = targetDoc["pres-text-viewed-color"] ? StrCast(targetDoc["pres-text-viewed-color"]) : "Black";
+            return (
+                <div>
+                    <div className={`presBox-ribbon ${this.progressivizeTools && this.layoutDoc.presStatus === "edit" ? "active" : ""}`} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
+                        <div className="ribbon-box">
+                            {this.stringType} selected
+                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
+                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.presProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeChild}>Contents</div>
+                                <div className="ribbon-toggle" style={{ opacity: activeItem.presProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editProgressivize}>Edit</div>
+                            </div>
+                            <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+                                <div className="presBox-subheading">Active text color</div>
+                                <div className="ribbon-colorBox" style={{ backgroundColor: activeFontColor, height: 15, width: 15 }} onClick={action(() => { this.openActiveColorPicker = !this.openActiveColorPicker; })}>
+                                </div>
+                            </div>
+                            {this.activeColorPicker}
+                            <div className="ribbon-doubleButton" style={{ display: activeItem.presProgressivize ? "inline-flex" : "none" }}>
+                                <div className="presBox-subheading">Viewed font color</div>
+                                <div className="ribbon-colorBox" style={{ backgroundColor: viewedFontColor, height: 15, width: 15 }} onClick={action(() => this.openViewedColorPicker = !this.openViewedColorPicker)}>
+                                </div>
+                            </div>
+                            {this.viewedColorPicker}
+                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: (targetDoc.type === DocumentType.COL && targetDoc._viewType === 'freeform') || targetDoc.type === DocumentType.IMG ? "inline-flex" : "none" }}>
+                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.zoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeZoom}>Zoom</div>
+                                <div className="ribbon-toggle" style={{ opacity: activeItem.zoomProgressivize ? 1 : 0.4, backgroundColor: activeItem.editZoomProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editZoomProgressivize}>Edit</div>
+                            </div>
+                            <div className="ribbon-doubleButton" style={{ borderTop: 'solid 1px darkgrey', display: targetDoc._viewType === "stacking" || targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF ? "inline-flex" : "none" }}>
+                                <div className="ribbon-toggle" style={{ backgroundColor: activeItem.scrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.progressivizeScroll}>Scroll</div>
+                                <div className="ribbon-toggle" style={{ opacity: activeItem.scrollProgressivize ? 1 : 0.4, backgroundColor: targetDoc.editScrollProgressivize ? Colors.LIGHT_BLUE : "" }} onClick={this.editScrollProgressivize}>Edit</div>
+                            </div>
+                        </div>
+                        <div className="ribbon-final-box">
+                            Frames
+                            <div className="ribbon-doubleButton">
+                                <div className="ribbon-frameSelector">
+                                    <div key="back" title="back frame" className="backKeyframe" onClick={e => { e.stopPropagation(); this.prevKeyframe(targetDoc, activeItem); }}>
+                                        <FontAwesomeIcon icon={"caret-left"} size={"lg"} />
+                                    </div>
+                                    <div key="num" title="toggle view all" className="numKeyframe" style={{ color: targetDoc.keyFrameEditing ? "white" : "black", backgroundColor: targetDoc.keyFrameEditing ? Colors.MEDIUM_BLUE : Colors.LIGHT_BLUE }}
+                                        onClick={action(() => targetDoc.keyFrameEditing = !targetDoc.keyFrameEditing)} >
+                                        {NumCast(targetDoc._currentFrame)}
+                                    </div>
+                                    <div key="fwd" title="forward frame" className="fwdKeyframe" onClick={e => { e.stopPropagation(); this.nextKeyframe(targetDoc, activeItem); }}>
+                                        <FontAwesomeIcon icon={"caret-right"} size={"lg"} />
+                                    </div>
+                                </div>
+                                <Tooltip title={<><div className="dash-tooltip">{"Last frame"}</div></>}><div className="ribbon-property">{NumCast(targetDoc.lastFrame)}</div></Tooltip>
+                            </div>
+                            <div className="ribbon-frameList">
+                                {this.frameListHeader}
+                                {this.frameList}
+                            </div>
+                            <div className="ribbon-toggle" style={{ height: 20, backgroundColor: Colors.LIGHT_BLUE }} onClick={() => console.log(" TODO: play frames")}>Play</div>
+                        </div>
+                    </div>
+                </div>
+            );
+        }
+    }
+
+    @undoBatch
+    @action
+    switchActive = (color: ColorState) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const val = String(color.hex);
+        targetDoc["pres-text-color"] = val;
+        return true;
+    }
+    @undoBatch
+    @action
+    switchPresented = (color: ColorState) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const val = String(color.hex);
+        targetDoc["pres-text-viewed-color"] = val;
+        return true;
+    }
+
+    @computed get activeColorPicker() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        return !this.openActiveColorPicker ? (null) : <SketchPicker onChange={this.switchActive}
+            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+                '#FFFFFF', '#f1efeb', 'transparent']}
+            color={StrCast(targetDoc["pres-text-color"])} />;
+    }
+
+    @computed get viewedColorPicker() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        return !this.openViewedColorPicker ? (null) : <SketchPicker onChange={this.switchPresented}
+            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
+                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
+                '#FFFFFF', '#f1efeb', 'transparent']}
+            color={StrCast(targetDoc["pres-text-viewed-color"])} />;
+    }
+
+    @action
+    turnOffEdit = (paths?: boolean) => {
+        // Turn off paths
+        if (paths) {
+            const srcContext = Cast(this.rootDoc.presCollection, Doc, null);
+            if (srcContext) this.togglePath(srcContext, true);
+        }
+        // Turn off the progressivize editors for each document
+        this.childDocs.forEach((doc) => {
+            doc.editSnapZoomProgressivize = false;
+            doc.editZoomProgressivize = false;
+            const targetDoc = Cast(doc.presentationTargetDoc, Doc, null);
+            if (targetDoc) {
+                targetDoc.editZoomProgressivize = false;
+                // targetDoc.editScrollProgressivize = false;
+            }
+        });
+    }
+
+    //Toggle whether the user edits or not
+    @action
+    editZoomProgressivize = (e: React.MouseEvent) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        if (!targetDoc.editZoomProgressivize) {
+            if (!activeItem.zoomProgressivize) activeItem.zoomProgressivize = true; targetDoc.zoomProgressivize = true;
+            targetDoc.editZoomProgressivize = true;
+            activeItem.editZoomProgressivize = true;
+        } else {
+            targetDoc.editZoomProgressivize = false;
+            activeItem.editZoomProgressivize = false;
+        }
+    }
+
+    //Toggle whether the user edits or not
+    @action
+    editScrollProgressivize = (e: React.MouseEvent) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        if (!targetDoc.editScrollProgressivize) {
+            if (!targetDoc.scrollProgressivize) { targetDoc.scrollProgressivize = true; activeItem.scrollProgressivize = true; }
+            targetDoc.editScrollProgressivize = true;
+        } else {
+            targetDoc.editScrollProgressivize = false;
+        }
+    }
+
+    //Progressivize Zoom
+    @action
+    progressivizeScroll = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem: Doc = this.activeItem;
+        activeItem.scrollProgressivize = !activeItem.scrollProgressivize;
+        const targetDoc: Doc = this.targetDoc;
+        targetDoc.scrollProgressivize = !targetDoc.scrollProgressivize;
+        // CollectionFreeFormDocumentView.setupScroll(targetDoc, NumCast(targetDoc._currentFrame));
+        if (targetDoc.editScrollProgressivize) {
+            targetDoc.editScrollProgressivize = false;
+            targetDoc._currentFrame = 0;
+            targetDoc.lastFrame = 0;
+        }
+    }
+
+    //Progressivize Zoom
+    @action
+    progressivizeZoom = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem: Doc = this.activeItem;
+        activeItem.zoomProgressivize = !activeItem.zoomProgressivize;
+        const targetDoc: Doc = this.targetDoc;
+        targetDoc.zoomProgressivize = !targetDoc.zoomProgressivize;
+        CollectionFreeFormDocumentView.setupZoom(activeItem, targetDoc);
+        if (activeItem.editZoomProgressivize) {
+            activeItem.editZoomProgressivize = false;
+            targetDoc._currentFrame = 0;
+            targetDoc.lastFrame = 0;
+        }
+    }
+
+    //Progressivize Child Docs
+    @action
+    editProgressivize = (e: React.MouseEvent) => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        targetDoc._currentFrame = targetDoc.lastFrame;
+        if (!targetDoc.editProgressivize) {
+            if (!activeItem.presProgressivize) { activeItem.presProgressivize = true; targetDoc.presProgressivize = true; }
+            targetDoc.editProgressivize = true;
+        } else {
+            targetDoc.editProgressivize = false;
+        }
+    }
+
+    @action
+    progressivizeChild = (e: React.MouseEvent) => {
+        e.stopPropagation();
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        if (!activeItem.presProgressivize) {
+            targetDoc.keyFrameEditing = false;
+            activeItem.presProgressivize = true;
+            targetDoc.presProgressivize = true;
+            targetDoc._currentFrame = 0;
+            docs.forEach((doc, i) => CollectionFreeFormDocumentView.setupKeyframes([doc], i, true));
+            targetDoc.lastFrame = targetDoc.lastFrame ? NumCast(targetDoc.lastFrame) : docs.length - 1;
+        } else {
+            // targetDoc.editProgressivize = false;
+            activeItem.presProgressivize = false;
+            targetDoc.presProgressivize = false;
+            targetDoc._currentFrame = 0;
+            targetDoc.keyFrameEditing = true;
+        }
+    }
+
+    @action
+    checkMovementLists = (doc: Doc, xlist: any, ylist: any) => {
+        const x: List<number> = xlist;
+        const y: List<number> = ylist;
+        const tags: JSX.Element[] = [];
+        let pathPoints = ""; //List of all of the pathpoints that need to be added
+        for (let i = 0; i < x.length - 1; i++) {
+            if (y[i] || x[i]) {
+                if (i === 0) pathPoints = (x[i] - 11) + "," + (y[i] + 33);
+                else pathPoints = pathPoints + " " + (x[i] - 11) + "," + (y[i] + 33);
+                tags.push(<div className="progressivizeMove-frame" style={{ position: 'absolute', top: y[i], left: x[i] }}>{i}</div>);
+            }
+        }
+        tags.push(<svg style={{ overflow: 'visible', position: 'absolute' }}><polyline
+            points={pathPoints}
+            style={{
+                position: 'absolute',
+                opacity: 1,
+                stroke: "#000000",
+                strokeWidth: 2,
+                strokeDasharray: '10 5',
+            }}
+            fill="none"
+        /></svg>);
+        return tags;
+    }
+
+    @observable
+    toggleDisplayMovement = (doc: Doc) => {
+        if (doc.displayMovement) doc.displayMovement = false;
+        else doc.displayMovement = true;
+    }
+
+    @action
+    checkList = (doc: Doc, list: any): number => {
+        const x: List<number> = list;
+        if (x && x.length >= NumCast(doc._currentFrame) + 1) {
+            return x[NumCast(doc._currentFrame)];
+        } else if (x) {
+            x.length = NumCast(doc._currentFrame) + 1;
+            x[NumCast(doc._currentFrame)] = x[NumCast(doc._currentFrame) - 1];
+            return x[NumCast(doc._currentFrame)];
+        } else return 100;
+    }
+
+    @computed get progressivizeChildDocs() {
+        const targetDoc: Doc = this.targetDoc;
+        const docs = DocListCast(targetDoc[Doc.LayoutFieldKey(targetDoc)]);
+        const tags: JSX.Element[] = [];
+        docs.forEach((doc, index) => {
+            if (doc["x-indexed"] && doc["y-indexed"]) {
+                tags.push(<div style={{ position: 'absolute', display: doc.displayMovement ? "block" : "none" }}>{this.checkMovementLists(doc, doc["x-indexed"], doc["y-indexed"])}</div>);
+            }
+            tags.push(
+                <div className="progressivizeButton" key={index} onPointerLeave={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0; }} onPointerOver={() => { if (NumCast(targetDoc._currentFrame) < NumCast(doc.appearFrame)) doc.opacity = 0.5; }} onClick={e => { this.toggleDisplayMovement(doc); e.stopPropagation(); }} style={{ backgroundColor: doc.displayMovement ? Colors.LIGHT_BLUE : "#c8c8c8", top: NumCast(doc.y), left: NumCast(doc.x) }}>
+                    <div className="progressivizeButton-prev"><FontAwesomeIcon icon={"caret-left"} size={"lg"} onClick={e => { e.stopPropagation(); this.prevAppearFrame(doc, index); }} /></div>
+                    <div className="progressivizeButton-frame">{doc.appearFrame}</div>
+                    <div className="progressivizeButton-next"><FontAwesomeIcon icon={"caret-right"} size={"lg"} onClick={e => { e.stopPropagation(); this.nextAppearFrame(doc, index); }} /></div>
+                </div>);
+        });
+        return tags;
+    }
+
+    @action
+    nextAppearFrame = (doc: Doc, i: number): void => {
+        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const appearFrame = Cast(doc.appearFrame, "number", null);
+        if (appearFrame === undefined) {
+            doc.appearFrame = 0;
+        }
+        doc.appearFrame = appearFrame + 1;
+        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
+    }
+
+    @action
+    prevAppearFrame = (doc: Doc, i: number): void => {
+        // const activeItem = Cast(this.childDocs[this.itemIndex], Doc, null);
+        // const targetDoc = Cast(activeItem?.presentationTargetDoc, Doc, null);
+        const appearFrame = Cast(doc.appearFrame, "number", null);
+        if (appearFrame === undefined) {
+            doc.appearFrame = 0;
+        }
+        doc.appearFrame = Math.max(0, appearFrame - 1);
+        this.updateOpacityList(doc["opacity-indexed"], NumCast(doc.appearFrame));
+    }
+
+    @action
+    updateOpacityList = (list: any, frame: number) => {
+        const x: List<number> = list;
+        if (x && x.length >= frame) {
+            for (let i = 0; i < x.length; i++) {
+                if (i < frame) {
+                    x[i] = 0;
+                } else if (i >= frame) {
+                    x[i] = 1;
+                }
+            }
+            list = x;
+        } else {
+            x.length = frame + 1;
+            for (let i = 0; i < x.length; i++) {
+                if (i < frame) {
+                    x[i] = 0;
+                } else if (i >= frame) {
+                    x[i] = 1;
+                }
+            }
+            list = x;
+        }
+    }
+
+    @computed get moreInfoDropdown() {
+        return (<div></div>);
+    }
+
+    @computed
+    get toolbarWidth(): number {
+        const width = this.props.PanelWidth();
+        return width;
+    }
+
+    @action
+    toggleProperties = () => {
+        if (CurrentUserUtils.propertiesWidth > 0) {
+            CurrentUserUtils.propertiesWidth = 0;
+        } else {
+            CurrentUserUtils.propertiesWidth = 250;
+        }
+    }
+
+    @computed get toolbar() {
+        const propIcon = CurrentUserUtils.propertiesWidth > 0 ? "angle-double-right" : "angle-double-left";
+        const propTitle = CurrentUserUtils.propertiesWidth > 0 ? "Close Presentation Panel" : "Open Presentation Panel";
+        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
+        const isMini: boolean = this.toolbarWidth <= 100;
+        const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === Doc.UserDoc().activePresentation);
+        const activeColor = Colors.LIGHT_BLUE;
+        const inactiveColor = Colors.WHITE;
+        return (mode === CollectionViewType.Carousel3D) ? (null) : (
+            <div id="toolbarContainer" className={'presBox-toolbar'}>
+                {/* <Tooltip title={<><div className="dash-tooltip">{"Add new slide"}</div></>}><div className={`toolbar-button ${this.newDocumentTools ? "active" : ""}`} onClick={action(() => this.newDocumentTools = !this.newDocumentTools)}>
+                    <FontAwesomeIcon icon={"plus"} />
+                    <FontAwesomeIcon className={`dropdown ${this.newDocumentTools ? "active" : ""}`} icon={"angle-down"} />
+                </div></Tooltip> */}
+                <Tooltip title={<><div className="dash-tooltip">{"View paths"}</div></>}>
+                    <div style={{ opacity: this.childDocs.length > 1 && this.layoutDoc.presCollection ? 1 : 0.3, color: this._pathBoolean ? Colors.MEDIUM_BLUE : 'white', width: isMini ? "100%" : undefined }} className={"toolbar-button"} onClick={this.childDocs.length > 1 && this.layoutDoc.presCollection ? this.viewPaths : undefined}>
+                        <FontAwesomeIcon icon={"exchange-alt"} />
+                    </div>
+                </Tooltip>
+                {isMini ? (null) :
+                    <>
+                        <div className="toolbar-divider" />
+                        {/* <Tooltip title={<><div className="dash-tooltip">{this._expandBoolean ? "Minimize all" : "Expand all"}</div></>}>
+                            <div className={"toolbar-button"}
+                                style={{ color: this._expandBoolean ? Colors.MEDIUM_BLUE : 'white' }}
+                                onClick={this.toggleExpandMode}>
+                                <FontAwesomeIcon icon={"eye"} />
+                            </div>
+                        </Tooltip>
+                        <div className="toolbar-divider" /> */}
+                        <Tooltip title={<><div className="dash-tooltip">{presKeyEvents ? "Keys are active" : "Keys are not active - click anywhere on the presentation trail to activate keys"}</div></>}>
+                            <div className="toolbar-button" style={{ cursor: presKeyEvents ? 'default' : 'pointer', position: 'absolute', right: 30, fontSize: 16 }}>
+                                <FontAwesomeIcon className={"toolbar-thumbtack"} icon={"keyboard"} style={{ color: presKeyEvents ? activeColor : inactiveColor }} />
+                            </div>
+                        </Tooltip>
+                        <Tooltip title={<><div className="dash-tooltip">{propTitle}</div></>}>
+                            <div className="toolbar-button" style={{ position: 'absolute', right: 4, fontSize: 16 }} onClick={this.toggleProperties}>
+                                <FontAwesomeIcon className={"toolbar-thumbtack"} icon={propIcon} style={{ color: CurrentUserUtils.propertiesWidth > 0 ? activeColor : inactiveColor }} />
+                            </div>
+                        </Tooltip>
+                    </>
+                }
+            </div>
+        );
+    }
+
+    /**
+     * Top panel containes:
+     * viewPicker: The option to choose between List and Slides view for the presentaiton trail
+     * presentPanel: The button to start the presentation / open minimized view of the presentation
+     */
+    @computed get topPanel() {
+        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
+        const isMini: boolean = this.toolbarWidth <= 100;
+        return (
+            <div className="presBox-buttons" style={{ display: !this.rootDoc._chromeHidden ? "none" : undefined }}>
+                {isMini ? (null) : <select className="presBox-viewPicker"
+                    style={{ display: this.layoutDoc.presStatus === "edit" ? "block" : "none" }}
+                    onPointerDown={e => e.stopPropagation()}
+                    onChange={this.viewChanged}
+                    value={mode}>
+                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Stacking}>List</option>
+                    <option onPointerDown={e => e.stopPropagation()} value={CollectionViewType.Carousel3D}>3D Carousel</option>
+                </select>}
+                <div className="presBox-presentPanel" style={{ opacity: this.childDocs.length ? 1 : 0.3 }}>
+                    <span className={`presBox-button ${this.layoutDoc.presStatus === "edit" ? "present" : ""}`}>
+                        <div className="presBox-button-left"
+                            onClick={undoBatch(() => {
+                                if (this.childDocs.length) {
+                                    this.layoutDoc.presStatus = "manual";
+                                    this.gotoDocument(this.itemIndex, this.activeItem);
+                                }
+                            })}>
+                            <FontAwesomeIcon icon={"play-circle"} />
+                            <div style={{ display: this.props.PanelWidth() > 200 ? "inline-flex" : "none" }}>&nbsp; Present</div>
+                        </div>
+                        {(mode === CollectionViewType.Carousel3D || isMini) ? (null) : <div className={`presBox-button-right ${this.presentTools ? "active" : ""}`}
+                            onClick={(action(() => {
+                                if (this.childDocs.length) this.presentTools = !this.presentTools;
+                            }))}>
+                            <FontAwesomeIcon className="dropdown" style={{ margin: 0, transform: this.presentTools ? 'rotate(180deg)' : 'rotate(0deg)' }} icon={"angle-down"} />
+                            {this.presentDropdown}
+                        </div>}
+                    </span>
+                    {this.playButtons}
+                </div>
+            </div>
+        );
+    }
+
+    @action
+    getList = (list: any): List<number> => {
+        const x: List<number> = list;
+        return x;
+    }
+
+    @action
+    updateList = (list: any): List<number> => {
+        const targetDoc: Doc = this.targetDoc;
+        const x: List<number> = list;
+        x.length + 1;
+        x[x.length - 1] = NumCast(targetDoc._scrollY);
+        return x;
+    }
+
+    @action
+    newFrame = () => {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const type: string = StrCast(targetDoc.type);
+        if (!activeItem.frameList) activeItem.frameList = new List<number>();
+        switch (type) {
+            case (DocumentType.PDF || DocumentType.RTF || DocumentType.WEB):
+                this.updateList(activeItem.frameList);
+                break;
+            case DocumentType.COL:
+                break;
+            default:
+                break;
+        }
+    }
+
+    @computed get frameListHeader() {
+        return (<div className="frameList-header">
+            &nbsp; Frames {this.panable ? <i>Panable</i> : this.scrollable ? <i>Scrollable</i> : (null)}
+            <div className={"frameList-headerButtons"}>
+                <Tooltip title={<><div className="dash-tooltip">{"Add frame by example"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); this.newFrame(); }}>
+                    <FontAwesomeIcon icon={"plus"} onPointerDown={e => e.stopPropagation()} />
+                </div></Tooltip>
+                <Tooltip title={<><div className="dash-tooltip">{"Edit in collection"}</div></>}><div className={"headerButton"} onClick={e => { e.stopPropagation(); console.log('New frame'); }}>
+                    <FontAwesomeIcon icon={"edit"} onPointerDown={e => e.stopPropagation()} />
+                </div></Tooltip>
+            </div>
+        </div>);
+    }
+
+    @computed get frameList() {
+        const activeItem: Doc = this.activeItem;
+        const targetDoc: Doc = this.targetDoc;
+        const frameList: List<number> = this.getList(activeItem.frameList);
+        if (frameList) {
+            const frameItems = frameList.map((value) =>
+                <div className="framList-item">
+
+                </div>
+            );
+            return (
+
+                <div className="frameList-container">
+                    {frameItems}
+                </div>
+            );
+        } else return (null);
+
+    }
+
+    @computed get playButtonFrames() {
+        const targetDoc: Doc = this.targetDoc;
+        return (
+            <>
+                {this.targetDoc ? <div className="presPanel-button-frame" style={{ display: targetDoc.lastFrame !== undefined && targetDoc.lastFrame >= 0 ? "inline-flex" : "none" }}>
+                    <div>{targetDoc._currentFrame}</div>
+                    <div className="presPanel-divider" style={{ border: 'solid 0.5px white', height: '60%' }}></div>
+                    <div>{targetDoc.lastFrame}</div>
+                </div> : null}
+            </>
+        );
+    }
+
+    @computed get playButtons() {
+        const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
+        const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
+        // Case 1: There are still other frames and should go through all frames before going to next slide
+        return (<div className="presPanelOverlay" style={{ display: this.layoutDoc.presStatus !== "edit" ? "inline-flex" : "none" }}>
+            <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : 'white' }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
+            <div className="presPanel-divider"></div>
+            <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div>
+            <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === PresStatus.Autoplay ? "pause" : "play"} /></div></Tooltip>
+            <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
+            <div className="presPanel-divider"></div>
+            <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip>
+            <div
+                className="presPanel-button-text"
+                onClick={() => this.gotoDocument(0, this.activeItem)}
+                style={{ display: this.props.PanelWidth() > 250 ? "inline-flex" : "none" }}>
+                Slide {this.itemIndex + 1} / {this.childDocs.length}
+                {this.playButtonFrames}
+            </div>
+            <div className="presPanel-divider"></div>
+            {this.props.PanelWidth() > 250 ? <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.layoutDoc.presStatus = "edit"; clearTimeout(this._presTimer); }))}>EXIT</div>
+                : <div className="presPanel-button" onClick={undoBatch(action(() => this.layoutDoc.presStatus = "edit"))}>
+                    <FontAwesomeIcon icon={"times"} />
+                </div>}
+        </div>);
+    }
+
+    @action
+    startOrPause = () => {
+        if (this.layoutDoc.presStatus === PresStatus.Manual || this.layoutDoc.presStatus === PresStatus.Edit) this.startAutoPres(this.itemIndex);
+        else this.pauseAutoPres();
+    }
+
+    render() {
+        // calling this method for keyEvents
+        this.isPres;
+        // needed to ensure that the childDocs are loaded for looking up fields
+        this.childDocs.slice();
+        const mode = StrCast(this.rootDoc._viewType) as CollectionViewType;
+        const presKeyEvents: boolean = (this.isPres && this._presKeyEventsActive && this.rootDoc === Doc.UserDoc().activePresentation);
+        const presEnd: boolean = !this.layoutDoc.presLoop && (this.itemIndex === this.childDocs.length - 1);
+        const presStart: boolean = !this.layoutDoc.presLoop && (this.itemIndex === 0);
+        return CurrentUserUtils.OverlayDocs.includes(this.rootDoc) ?
+            <div className="miniPres">
+                <div className="presPanelOverlay" style={{ display: "inline-flex", height: 30, background: '#323232', top: 0, zIndex: 3000000, boxShadow: presKeyEvents ? '0 0 0px 3px ' + Colors.MEDIUM_BLUE : undefined }}>
+                    <Tooltip title={<><div className="dash-tooltip">{"Loop"}</div></>}><div className="presPanel-button" style={{ color: this.layoutDoc.presLoop ? Colors.MEDIUM_BLUE : undefined }} onClick={() => this.layoutDoc.presLoop = !this.layoutDoc.presLoop}><FontAwesomeIcon icon={"redo-alt"} /></div></Tooltip>
+                    <div className="presPanel-divider"></div>
+                    <div className="presPanel-button" style={{ opacity: presStart ? 0.4 : 1 }} onClick={() => { this.back(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-left"} /></div>
+                    <Tooltip title={<><div className="dash-tooltip">{this.layoutDoc.presStatus === PresStatus.Autoplay ? "Pause" : "Autoplay"}</div></>}><div className="presPanel-button" onClick={this.startOrPause}><FontAwesomeIcon icon={this.layoutDoc.presStatus === "auto" ? "pause" : "play"} /></div></Tooltip>
+                    <div className="presPanel-button" style={{ opacity: presEnd ? 0.4 : 1 }} onClick={() => { this.next(); if (this._presTimer) { clearTimeout(this._presTimer); this.layoutDoc.presStatus = PresStatus.Manual; } }}><FontAwesomeIcon icon={"arrow-right"} /></div>
+                    <div className="presPanel-divider"></div>
+                    <Tooltip title={<><div className="dash-tooltip">{"Click to return to 1st slide"}</div></>}><div className="presPanel-button" style={{ border: 'solid 1px white' }} onClick={() => this.gotoDocument(0, this.activeItem)}><b>1</b></div></Tooltip>
+                    <div className="presPanel-button-text">
+                        Slide {this.itemIndex + 1} / {this.childDocs.length}
+                        {this.playButtonFrames}
+                    </div>
+                    <div className="presPanel-divider"></div>
+                    <div className="presPanel-button-text" onClick={undoBatch(action(() => { this.updateMinimize(); this.layoutDoc.presStatus = PresStatus.Edit; clearTimeout(this._presTimer); }))}>EXIT</div>
+                </div>
+            </div>
+            :
+            <div className="presBox-cont" style={{ minWidth: CurrentUserUtils.OverlayDocs.includes(this.layoutDoc) ? 240 : undefined }} >
+                {this.topPanel}
+                {this.toolbar}
+                {this.newDocumentToolbarDropdown}
+                <div className="presBox-listCont">
+                    {mode !== CollectionViewType.Invalid ?
+                        <CollectionView {...this.props}
+                            ContainingCollectionDoc={this.props.Document}
+                            PanelWidth={this.props.PanelWidth}
+                            PanelHeight={this.panelHeight}
+                            childIgnoreNativeSize={true}
+                            moveDocument={returnFalse}
+                            childFitWidth={returnTrue}
+                            childOpacity={returnOne}
+                            childLayoutTemplate={this.childLayoutTemplate}
+                            filterAddDocument={this.addDocumentFilter}
+                            removeDocument={returnFalse}
+                            dontRegisterView={true}
+                            focus={this.selectElement}
+                            ScreenToLocalTransform={this.getTransform}
+                        />
+                        : (null)
+                    }
+                </div>
+            </div>;
+    }
+}
+Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, data: Doc) {
+    if (field === 'indexInPres') return DocListCast(container[StrCast(container.presentationFieldKey)]).indexOf(data);
+    if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 35 : 31;
+    if (field === 'presStatus') return container.presStatus;
+    if (field === '_itemIndex') return container._itemIndex;
+    if (field === 'presBox') return container;
+    return undefined;
+});
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresElementBox.scss b/src/client/views/nodes/trails/PresElementBox.scss
new file mode 100644
index 000000000..1ad4b820e
--- /dev/null
+++ b/src/client/views/nodes/trails/PresElementBox.scss
@@ -0,0 +1,235 @@
+$light-blue: #AEDDF8;
+$dark-blue: #5B9FDD;
+$light-background: #ececec;
+$slide-background: #d5dce2;
+$slide-active: #5B9FDD;
+
+.presItem-container {
+    cursor: grab;
+    display: grid;
+    grid-template-columns: 20px auto;
+    font-family: Roboto;
+    letter-spacing: normal;
+    position: relative;
+    pointer-events: all;
+    width: 100%;
+    height: 100%;
+    font-weight: 400;
+    -webkit-touch-callout: none;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    align-items: center;
+
+    .presItem-number {
+        margin-top: 3.5px;
+        font-size: 12px;
+        font-weight: 700;
+        text-align: center;
+        justify-self: center;
+        align-self: flex-start;
+        position: relative;
+        display: inline-block;
+        overflow: hidden;
+    }
+
+}
+
+.presItem-slide {
+    position: relative;
+    background-color: #d5dce2;
+    border-radius: 5px;
+    height: calc(100% - 7px);
+    width: calc(100% - 15px);
+    display: grid;
+    grid-template-rows: 16px 10px auto;
+    grid-template-columns: max-content max-content max-content max-content auto;
+
+    .presItem-name {
+        min-width: 20px;
+        z-index: 300;
+        top: 2px;
+        align-self: center;
+        font-size: 11px;
+        font-family: Roboto;
+        font-weight: 500;
+        position: relative;
+        padding-left: 10px;
+        padding-right: 10px;
+        letter-spacing: normal;
+        width: max-content;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: pre;
+    }
+
+    .presItem-docName {
+        min-width: 20px;
+        z-index: 300;
+        align-self: center;
+        font-size: 9px;
+        font-family: Roboto;
+        font-weight: 300;
+        position: relative;
+        padding-left: 10px;
+        padding-right: 10px;
+        letter-spacing: normal;
+        width: max-content;
+        text-overflow: ellipsis;
+        overflow: hidden;
+        white-space: pre;
+        grid-row: 2;
+        grid-column: 1/6;
+    }
+
+    .presItem-time {
+        align-self: center;
+        position: relative;
+        padding-right: 10px;
+        top: 1px;
+        font-size: 10;
+        font-weight: 300;
+        font-family: Roboto;
+        z-index: 300;
+        letter-spacing: normal;
+    }
+
+    .presItem-embedded {
+        overflow: hidden;
+        grid-row: 3;
+        grid-column: 1/8;
+        position: relative;
+        display: flex;
+        width: auto;
+        justify-content: center;
+        margin: auto;
+        margin-bottom: 2px;
+        border-bottom-left-radius: 5px;
+        border-bottom-right-radius: 5px;
+    }
+
+    .presItem-embeddedMask {
+        width: 100%;
+        height: 100%;
+        position: absolute;
+        border-radius: 3px;
+        top: 0;
+        left: 0;
+        z-index: 1;
+        overflow: hidden;
+    }
+
+
+    .presItem-slideButtons {
+        display: flex;
+        grid-column: 7;
+        grid-row: 1/3;
+        width: max-content;
+        justify-self: right;
+        justify-content: flex-end;
+
+        .slideButton {
+            cursor: pointer;
+            position: relative;
+            border-radius: 100px;
+            z-index: 300;
+            width: 18px;
+            height: 18px;
+            display: flex;
+            font-size: 12px;
+            justify-self: center;
+            align-self: center;
+            background-color: rgba(0, 0, 0, 0.5);
+            color: white;
+            justify-content: center;
+            align-items: center;
+            transition: 0.2s;
+            margin-right: 3px;
+        }
+
+        .slideButton:hover {
+            background-color: rgba(0, 0, 0, 1);
+            transform: scale(1.2);
+        }
+    }
+}
+
+// .presItem-slide:hover {
+//     .presItem-slideButtons {
+//         display: flex;
+//         grid-column: 7;
+//         grid-row: 1/3;
+//         width: max-content;
+//         justify-self: right;
+//         justify-content: flex-end;
+
+//         .slideButton {
+//             cursor: pointer;
+//             position: relative;
+//             border-radius: 100px;
+//             z-index: 300;
+//             width: 18px;
+//             height: 18px;
+//             display: flex;
+//             font-size: 12px;
+//             justify-self: center;
+//             align-self: center;
+//             background-color: rgba(0, 0, 0, 0.5);
+//             color: white;
+//             justify-content: center;
+//             align-items: center;
+//             transition: 0.2s;
+//             margin-right: 3px;
+//         }
+
+//         .slideButton:hover {
+//             background-color: rgba(0, 0, 0, 1);
+//             transform: scale(1.2);
+//         }
+//     }
+// }
+
+.presItem-slide.active {
+    box-shadow: 0 0 0px 1.5px $dark-blue;
+}
+
+.presItem-multiDrag {
+    font-family: Roboto;
+    font-weight: 600;
+    color: white;
+    text-align: center;
+    justify-content: center;
+    align-content: center;
+    width: 100px;
+    height: 30px;
+    position: absolute;
+    background-color: $dark-blue;
+    z-index: 4000;
+    border-radius: 10px;
+    box-shadow: black 0.4vw 0.4vw 0.8vw;
+    line-height: 30px;
+}
+
+.presItem-miniSlide {
+    font-weight: 700;
+    font-size: 12;
+    grid-column: 1/8;
+    align-self: center;
+    justify-self: center;
+    background-color: #d5dce2;
+    width: 26px;
+    text-align: center;
+    height: 26px;
+    line-height: 28px;
+    border-radius: 100%;
+}
+
+.presItem-miniSlide.active {
+    box-shadow: 0 0 0px 1.5px $dark-blue;
+}
+
+// .presItem-slide:hover {
+//     background: $slide-hover;
+// }
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
new file mode 100644
index 000000000..5e713c3cf
--- /dev/null
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -0,0 +1,388 @@
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Tooltip } from "@material-ui/core";
+import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
+import { observer } from "mobx-react";
+import { DataSym, Doc, Opt } from "../../../../fields/Doc";
+import { documentSchema } from '../../../../fields/documentSchemas';
+import { Id } from "../../../../fields/FieldSymbols";
+import { createSchema, makeInterface } from '../../../../fields/Schema';
+import { Cast, NumCast, StrCast } from "../../../../fields/Types";
+import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, emptyPath, returnEmptyDoclist } from "../../../../Utils";
+import { DocumentType } from "../../../documents/DocumentTypes";
+import { CurrentUserUtils } from "../../../util/CurrentUserUtils";
+import { DocumentManager } from "../../../util/DocumentManager";
+import { DragManager } from "../../../util/DragManager";
+import { Transform } from "../../../util/Transform";
+import { undoBatch } from "../../../util/UndoManager";
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { EditableView } from "../../EditableView";
+import { DocumentView, DocumentViewProps } from "../../nodes/DocumentView";
+import { FieldView, FieldViewProps } from '../../nodes/FieldView';
+import { PresBox } from "./PresBox";
+import { Colors } from "../../global/globalEnums";
+import { StyleProp } from "../../StyleProvider";
+import "./PresElementBox.scss";
+import React = require("react");
+import { DocUtils } from "../../../documents/Documents";
+import { PresMovement } from "./PresEnums";
+
+export const presSchema = createSchema({
+    presentationTargetDoc: Doc,
+    presBox: Doc,
+    presZoomButton: "boolean",
+    presNavButton: "boolean",
+    presHideTillShownButton: "boolean",
+    presFadeButton: "boolean",
+    presHideAfterButton: "boolean",
+    presGroupButton: "boolean",
+    presExpandInlineButton: "boolean"
+});
+
+type PresDocument = makeInterface<[typeof presSchema, typeof documentSchema]>;
+const PresDocument = makeInterface(presSchema, documentSchema);
+/**
+ * This class models the view a document added to presentation will have in the presentation.
+ * It involves some functionality for its buttons and options.
+ */
+@observer
+export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
+    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
+    _heightDisposer: IReactionDisposer | undefined;
+
+    @observable _dragging = false;
+    // these fields are conditionally computed fields on the layout document that take this document as a parameter
+    @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
+    @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
+    @computed get presStatus() { return StrCast(this.lookupField("presStatus")); }
+    @computed get itemIndex() { return NumCast(this.lookupField("_itemIndex")); }
+    @computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); }
+    @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
+
+    componentDidMount() {
+        this.layoutDoc.hideLinkButton = true;
+        this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
+            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true });
+    }
+    componentWillUnmount() {
+        this._heightDisposer?.();
+    }
+
+    /**
+     * Returns a local transformed coordinate array for given coordinates.
+     */
+    ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord];
+
+    @action
+    presExpandDocumentClick = () => {
+        this.rootDoc.presExpandInlineButton = !this.rootDoc.presExpandInlineButton;
+    }
+
+    embedHeight = (): number => 97;
+    // embedWidth = () => this.props.PanelWidth();
+    // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight);
+    embedWidth = (): number => this.props.PanelWidth() - 35;
+    styleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => {
+        if (property === StyleProp.Opacity) return 1;
+        return this.props.styleProvider?.(doc, props, property);
+    }
+    /**
+     * The function that is responsible for rendering a preview or not for this
+     * presentation element.
+     */
+    @computed get renderEmbeddedInline() {
+        return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
+            <div className="presItem-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
+                <DocumentView
+                    Document={this.targetDoc}
+                    DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
+                    styleProvider={this.styleProvider}
+                    layerProvider={this.props.layerProvider}
+                    docViewPath={returnEmptyDoclist}
+                    rootSelected={returnTrue}
+                    addDocument={returnFalse}
+                    removeDocument={returnFalse}
+                    isContentActive={this.props.isContentActive}
+                    addDocTab={returnFalse}
+                    pinToPres={returnFalse}
+                    PanelWidth={this.embedWidth}
+                    PanelHeight={this.embedHeight}
+                    ScreenToLocalTransform={Transform.Identity}
+                    moveDocument={this.props.moveDocument!}
+                    renderDepth={this.props.renderDepth + 1}
+                    focus={DocUtils.DefaultFocus}
+                    whenChildContentsActiveChanged={returnFalse}
+                    bringToFront={returnFalse}
+                    docFilters={this.props.docFilters}
+                    docRangeFilters={this.props.docRangeFilters}
+                    searchFilterDocs={this.props.searchFilterDocs}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined}
+                    hideLinkButton={true}
+                />
+                <div className="presItem-embeddedMask" />
+            </div>;
+    }
+
+    @computed get duration() {
+        let durationInS: number;
+        if (this.rootDoc.type === DocumentType.AUDIO || this.rootDoc.type === DocumentType.VID) { durationInS = NumCast(this.rootDoc.presEndTime) - NumCast(this.rootDoc.presStartTime); durationInS = Math.round(durationInS * 10) / 10; }
+        else if (this.rootDoc.presDuration) durationInS = NumCast(this.rootDoc.presDuration) / 1000;
+        else durationInS = 2;
+        return "D: " + durationInS + "s";
+    }
+
+    @computed get transition() {
+        let transitionInS: number;
+        if (this.rootDoc.presTransition) transitionInS = NumCast(this.rootDoc.presTransition) / 1000;
+        else transitionInS = 0.5;
+        return this.rootDoc.presMovement === PresMovement.Jump || this.rootDoc.presMovement === PresMovement.None ? (null) : "M: " + transitionInS + "s";
+    }
+
+    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _dragRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _titleRef: React.RefObject<EditableView> = React.createRef();
+
+
+    @action
+    headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        const element = e.target as any;
+        e.stopPropagation();
+        e.preventDefault();
+        if (element && !(e.ctrlKey || e.metaKey)) {
+            if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
+                PresBox.Instance._selectedArray.size === 1 && PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false);
+                setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
+            } else {
+                setupMoveUpEvents(this, e, ((e: PointerEvent) => {
+                    PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false);
+                    return this.startDrag(e);
+                }), emptyFunction, emptyFunction);
+            }
+        }
+    }
+
+    headerUp = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    startDrag = (e: PointerEvent) => {
+        const miniView: boolean = this.toolbarWidth <= 100;
+        const activeItem = this.rootDoc;
+        const dragArray = PresBox.Instance._dragArray;
+        const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray());
+        const dragItem: HTMLElement[] = [];
+        if (dragArray.length === 1) {
+            const doc = dragArray[0];
+            doc.className = miniView ? "presItem-miniSlide" : "presItem-slide";
+            dragItem.push(doc);
+        } else if (dragArray.length >= 1) {
+            const doc = document.createElement('div');
+            doc.className = "presItem-multiDrag";
+            doc.innerText = "Move " + PresBox.Instance._selectedArray.size + " slides";
+            doc.style.position = 'absolute';
+            doc.style.top = (e.clientY) + 'px';
+            doc.style.left = (e.clientX - 50) + 'px';
+            dragItem.push(doc);
+        }
+
+        // const dropEvent = () => runInAction(() => this._dragging = false);
+        if (activeItem) {
+            DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined);
+            // runInAction(() => this._dragging = true);
+            return true;
+        }
+        return false;
+    }
+
+    onPointerOver = (e: any) => {
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.addEventListener("pointermove", this.onPointerMove);
+    }
+
+    onPointerMove = (e: PointerEvent) => {
+        const slide = this._itemRef.current!;
+        let dragIsPresItem: boolean = DragManager.docsBeingDragged.length > 0 ? true : false;
+        for (const doc of DragManager.docsBeingDragged) {
+            if (!doc.presentationTargetDoc) dragIsPresItem = false;
+        }
+        if (slide && dragIsPresItem) {
+            const rect = slide.getBoundingClientRect();
+            const y = e.clientY - rect.top;  //y position within the element.
+            const height = slide.clientHeight;
+            const halfLine = height / 2;
+            if (y <= halfLine) {
+                slide.style.borderTop = `solid 2px ${Colors.MEDIUM_BLUE}`;
+                slide.style.borderBottom = "0px";
+            } else if (y > halfLine) {
+                slide.style.borderTop = "0px";
+                slide.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`;
+            }
+        }
+        document.removeEventListener("pointermove", this.onPointerMove);
+    }
+
+    onPointerLeave = (e: any) => {
+        this._itemRef.current!.style.borderTop = "0px";
+        this._itemRef.current!.style.borderBottom = "0px";
+        document.removeEventListener("pointermove", this.onPointerMove);
+    }
+
+    @action
+    toggleProperties = () => {
+        if (CurrentUserUtils.propertiesWidth < 5) {
+            action(() => (CurrentUserUtils.propertiesWidth = 250));
+        }
+    }
+
+    @undoBatch
+    removeItem = action((e: React.MouseEvent) => {
+        this.props.removeDocument?.(this.rootDoc);
+        if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
+            PresBox.Instance._selectedArray.delete(this.rootDoc);
+        }
+        e.stopPropagation();
+    });
+
+    @undoBatch
+    @action
+    onSetValue = (value: string) => {
+        this.rootDoc.title = !value.trim().length ? "-untitled-" : value;
+        return true;
+    }
+
+    /**
+     * Method called for updating the view of the currently selected document
+     * 
+     * @param targetDoc 
+     * @param activeItem 
+     */
+    @undoBatch
+    @action
+    updateView = (targetDoc: Doc, activeItem: Doc) => {
+        if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
+            const scroll = targetDoc._scrollTop;
+            activeItem.presPinViewScroll = scroll;
+        } else if (targetDoc.type === DocumentType.VID) {
+            activeItem.presPinTimecode = targetDoc._currentTimecode;
+        } else if (targetDoc.type === DocumentType.COMPARISON) {
+            const clipWidth = targetDoc._clipWidth;
+            activeItem.presPinClipWidth = clipWidth;
+        } else {
+            const x = targetDoc._panX;
+            const y = targetDoc._panY;
+            const scale = targetDoc._viewScale;
+            activeItem.presPinViewX = x;
+            activeItem.presPinViewY = y;
+            activeItem.presPinViewScale = scale;
+        }
+    }
+
+    @computed
+    get toolbarWidth(): number {
+        const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox);
+        let width: number = NumCast(this.presBox._width);
+        if (presBoxDocView) width = presBoxDocView.props.PanelWidth();
+        if (width === 0) width = 300;
+        return width;
+    }
+
+    @computed get mainItem() {
+        const isSelected: boolean = PresBox.Instance._selectedArray.has(this.rootDoc);
+        const toolbarWidth: number = this.toolbarWidth;
+        const showMore: boolean = this.toolbarWidth >= 300;
+        const miniView: boolean = this.toolbarWidth <= 110;
+        const presBox: Doc = this.presBox; //presBox
+        const presBoxColor: string = StrCast(presBox._backgroundColor);
+        const presColorBool: boolean = presBoxColor ? (presBoxColor !== Colors.WHITE && presBoxColor !== "transparent") : false;
+        const targetDoc: Doc = this.targetDoc;
+        const activeItem: Doc = this.rootDoc;
+        return (
+            <div className={`presItem-container`}
+                key={this.props.Document[Id] + this.indexInPres}
+                ref={this._itemRef}
+                style={{
+                    backgroundColor: presColorBool ? isSelected ? "rgba(250,250,250,0.3)" : "transparent" : isSelected ? Colors.LIGHT_BLUE : "transparent",
+                    opacity: this._dragging ? 0.3 : 1
+                }}
+                onClick={e => {
+                    e.stopPropagation();
+                    e.preventDefault();
+                    PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
+                }}
+                onDoubleClick={action(e => {
+                    this.toggleProperties();
+                    PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true);
+                })}
+                onPointerOver={this.onPointerOver}
+                onPointerLeave={this.onPointerLeave}
+                onPointerDown={this.headerDown}
+                onPointerUp={this.headerUp}
+            >
+                {miniView ?
+                    // when width is LESS than 110 px 
+                    <div className={`presItem-miniSlide ${isSelected ? "active" : ""}`} ref={miniView ? this._dragRef : null}>
+                        {`${this.indexInPres + 1}.`}
+                    </div>
+                    :
+                    // when width is MORE than 110 px 
+                    <div className="presItem-number">
+                        {`${this.indexInPres + 1}.`}
+                    </div>}
+                {miniView ? (null) : <div ref={miniView ? null : this._dragRef} className={`presItem-slide ${isSelected ? "active" : ""}`}
+                    style={{
+                        backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
+                        boxShadow: presBoxColor && presBoxColor !== "white" && presBoxColor !== "transparent" ? isSelected ? "0 0 0px 1.5px" + presBoxColor : undefined : undefined
+                    }}>
+                    <div className="presItem-name" style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105, cursor: isSelected ? 'text' : 'grab' }}>
+                        <EditableView
+                            ref={this._titleRef}
+                            editing={!isSelected ? false : undefined}
+                            contents={activeItem.title}
+                            overflow={'ellipsis'}
+                            GetValue={() => StrCast(activeItem.title)}
+                            SetValue={this.onSetValue}
+                        />
+                    </div>
+                    <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.transition}</div></Tooltip>
+                    <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.duration}</div></Tooltip>
+                    <div className={"presItem-slideButtons"}>
+                        <Tooltip title={<><div className="dash-tooltip">{"Update view"}</div></>}>
+                            <div className="slideButton"
+                                onClick={() => this.updateView(targetDoc, activeItem)}
+                                style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V</div>
+                        </Tooltip>
+                        {this.indexInPres === 0 ? (null) : <Tooltip title={<><div className="dash-tooltip">{activeItem.groupWithUp ? "Ungroup" : "Group with up"}</div></>}>
+                            <div className="slideButton"
+                                onClick={() => activeItem.groupWithUp = !activeItem.groupWithUp}
+                                style={{
+                                    zIndex: 1000 - this.indexInPres,
+                                    fontWeight: 700,
+                                    backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : Colors.MEDIUM_BLUE : undefined,
+                                    height: activeItem.groupWithUp ? 53 : 18,
+                                    transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined
+                                }}>
+                                <div style={{ transform: activeItem.groupWithUp ? "rotate(180deg) translate(0, -17.5px)" : "rotate(0deg)" }}>
+                                    <FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} />
+                                </div>
+                            </div>
+                        </Tooltip>}
+                        <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}</div></>}><div className={"slideButton"} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
+                            <FontAwesomeIcon icon={this.rootDoc.presExpandInlineButton ? "eye-slash" : "eye"} onPointerDown={e => e.stopPropagation()} />
+                        </div></Tooltip>
+                        <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
+                            className={"slideButton"}
+                            onClick={this.removeItem}>
+                            <FontAwesomeIcon icon={"trash"} onPointerDown={e => e.stopPropagation()} />
+                        </div></Tooltip>
+                    </div>
+                    <div className="presItem-docName" style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105 }}>{activeItem.presPinView ? (<><i>View of </i> {targetDoc.title}</>) : targetDoc.title}</div>
+                    {this.renderEmbeddedInline}
+                </div>}
+            </div >);
+    }
+
+    render() {
+        return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : this.mainItem;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/PresEnums.ts b/src/client/views/nodes/trails/PresEnums.ts
new file mode 100644
index 000000000..93ab323fb
--- /dev/null
+++ b/src/client/views/nodes/trails/PresEnums.ts
@@ -0,0 +1,28 @@
+export enum PresMovement {
+    Zoom = "zoom",
+    Pan = "pan",
+    Jump = "jump",
+    None = "none",
+}
+
+export enum PresEffect {
+    Zoom = "Zoom",
+    Lightspeed = "Lightspeed",
+    Fade = "Fade in",
+    Flip = "Flip",
+    Rotate = "Rotate",
+    Bounce = "Bounce",
+    Roll = "Roll",
+    None = "None",
+    Left = "left",
+    Right = "right",
+    Center = "center",
+    Top = "top",
+    Bottom = "bottom"
+}
+
+export enum PresStatus {
+    Autoplay = "auto",
+    Manual = "manual",
+    Edit = "edit"
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/trails/index.ts b/src/client/views/nodes/trails/index.ts
new file mode 100644
index 000000000..8f3f7b03a
--- /dev/null
+++ b/src/client/views/nodes/trails/index.ts
@@ -0,0 +1,3 @@
+export * from "./PresBox";
+export * from "./PresElementBox";
+export * from "./PresEnums";
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.scss b/src/client/views/presentationview/PresElementBox.scss
deleted file mode 100644
index 1ad4b820e..000000000
--- a/src/client/views/presentationview/PresElementBox.scss
+++ /dev/null
@@ -1,235 +0,0 @@
-$light-blue: #AEDDF8;
-$dark-blue: #5B9FDD;
-$light-background: #ececec;
-$slide-background: #d5dce2;
-$slide-active: #5B9FDD;
-
-.presItem-container {
-    cursor: grab;
-    display: grid;
-    grid-template-columns: 20px auto;
-    font-family: Roboto;
-    letter-spacing: normal;
-    position: relative;
-    pointer-events: all;
-    width: 100%;
-    height: 100%;
-    font-weight: 400;
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -khtml-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none;
-    align-items: center;
-
-    .presItem-number {
-        margin-top: 3.5px;
-        font-size: 12px;
-        font-weight: 700;
-        text-align: center;
-        justify-self: center;
-        align-self: flex-start;
-        position: relative;
-        display: inline-block;
-        overflow: hidden;
-    }
-
-}
-
-.presItem-slide {
-    position: relative;
-    background-color: #d5dce2;
-    border-radius: 5px;
-    height: calc(100% - 7px);
-    width: calc(100% - 15px);
-    display: grid;
-    grid-template-rows: 16px 10px auto;
-    grid-template-columns: max-content max-content max-content max-content auto;
-
-    .presItem-name {
-        min-width: 20px;
-        z-index: 300;
-        top: 2px;
-        align-self: center;
-        font-size: 11px;
-        font-family: Roboto;
-        font-weight: 500;
-        position: relative;
-        padding-left: 10px;
-        padding-right: 10px;
-        letter-spacing: normal;
-        width: max-content;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: pre;
-    }
-
-    .presItem-docName {
-        min-width: 20px;
-        z-index: 300;
-        align-self: center;
-        font-size: 9px;
-        font-family: Roboto;
-        font-weight: 300;
-        position: relative;
-        padding-left: 10px;
-        padding-right: 10px;
-        letter-spacing: normal;
-        width: max-content;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        white-space: pre;
-        grid-row: 2;
-        grid-column: 1/6;
-    }
-
-    .presItem-time {
-        align-self: center;
-        position: relative;
-        padding-right: 10px;
-        top: 1px;
-        font-size: 10;
-        font-weight: 300;
-        font-family: Roboto;
-        z-index: 300;
-        letter-spacing: normal;
-    }
-
-    .presItem-embedded {
-        overflow: hidden;
-        grid-row: 3;
-        grid-column: 1/8;
-        position: relative;
-        display: flex;
-        width: auto;
-        justify-content: center;
-        margin: auto;
-        margin-bottom: 2px;
-        border-bottom-left-radius: 5px;
-        border-bottom-right-radius: 5px;
-    }
-
-    .presItem-embeddedMask {
-        width: 100%;
-        height: 100%;
-        position: absolute;
-        border-radius: 3px;
-        top: 0;
-        left: 0;
-        z-index: 1;
-        overflow: hidden;
-    }
-
-
-    .presItem-slideButtons {
-        display: flex;
-        grid-column: 7;
-        grid-row: 1/3;
-        width: max-content;
-        justify-self: right;
-        justify-content: flex-end;
-
-        .slideButton {
-            cursor: pointer;
-            position: relative;
-            border-radius: 100px;
-            z-index: 300;
-            width: 18px;
-            height: 18px;
-            display: flex;
-            font-size: 12px;
-            justify-self: center;
-            align-self: center;
-            background-color: rgba(0, 0, 0, 0.5);
-            color: white;
-            justify-content: center;
-            align-items: center;
-            transition: 0.2s;
-            margin-right: 3px;
-        }
-
-        .slideButton:hover {
-            background-color: rgba(0, 0, 0, 1);
-            transform: scale(1.2);
-        }
-    }
-}
-
-// .presItem-slide:hover {
-//     .presItem-slideButtons {
-//         display: flex;
-//         grid-column: 7;
-//         grid-row: 1/3;
-//         width: max-content;
-//         justify-self: right;
-//         justify-content: flex-end;
-
-//         .slideButton {
-//             cursor: pointer;
-//             position: relative;
-//             border-radius: 100px;
-//             z-index: 300;
-//             width: 18px;
-//             height: 18px;
-//             display: flex;
-//             font-size: 12px;
-//             justify-self: center;
-//             align-self: center;
-//             background-color: rgba(0, 0, 0, 0.5);
-//             color: white;
-//             justify-content: center;
-//             align-items: center;
-//             transition: 0.2s;
-//             margin-right: 3px;
-//         }
-
-//         .slideButton:hover {
-//             background-color: rgba(0, 0, 0, 1);
-//             transform: scale(1.2);
-//         }
-//     }
-// }
-
-.presItem-slide.active {
-    box-shadow: 0 0 0px 1.5px $dark-blue;
-}
-
-.presItem-multiDrag {
-    font-family: Roboto;
-    font-weight: 600;
-    color: white;
-    text-align: center;
-    justify-content: center;
-    align-content: center;
-    width: 100px;
-    height: 30px;
-    position: absolute;
-    background-color: $dark-blue;
-    z-index: 4000;
-    border-radius: 10px;
-    box-shadow: black 0.4vw 0.4vw 0.8vw;
-    line-height: 30px;
-}
-
-.presItem-miniSlide {
-    font-weight: 700;
-    font-size: 12;
-    grid-column: 1/8;
-    align-self: center;
-    justify-self: center;
-    background-color: #d5dce2;
-    width: 26px;
-    text-align: center;
-    height: 26px;
-    line-height: 28px;
-    border-radius: 100%;
-}
-
-.presItem-miniSlide.active {
-    box-shadow: 0 0 0px 1.5px $dark-blue;
-}
-
-// .presItem-slide:hover {
-//     background: $slide-hover;
-// }
\ No newline at end of file
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
deleted file mode 100644
index f15d51764..000000000
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ /dev/null
@@ -1,386 +0,0 @@
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from "@material-ui/core";
-import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
-import { observer } from "mobx-react";
-import { DataSym, Doc, Opt } from "../../../fields/Doc";
-import { documentSchema } from '../../../fields/documentSchemas';
-import { Id } from "../../../fields/FieldSymbols";
-import { createSchema, makeInterface } from '../../../fields/Schema';
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { emptyFunction, returnFalse, returnTrue, setupMoveUpEvents, emptyPath, returnEmptyDoclist } from "../../../Utils";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { DocumentManager } from "../../util/DocumentManager";
-import { DragManager } from "../../util/DragManager";
-import { Transform } from "../../util/Transform";
-import { undoBatch } from "../../util/UndoManager";
-import { ViewBoxBaseComponent } from '../DocComponent';
-import { EditableView } from "../EditableView";
-import { DocumentView, DocumentViewProps } from "../nodes/DocumentView";
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
-import { PresBox, PresColor, PresMovement } from "../nodes/PresBox";
-import { StyleProp } from "../StyleProvider";
-import "./PresElementBox.scss";
-import React = require("react");
-import { DocUtils } from "../../documents/Documents";
-
-export const presSchema = createSchema({
-    presentationTargetDoc: Doc,
-    presBox: Doc,
-    presZoomButton: "boolean",
-    presNavButton: "boolean",
-    presHideTillShownButton: "boolean",
-    presFadeButton: "boolean",
-    presHideAfterButton: "boolean",
-    presGroupButton: "boolean",
-    presExpandInlineButton: "boolean"
-});
-
-type PresDocument = makeInterface<[typeof presSchema, typeof documentSchema]>;
-const PresDocument = makeInterface(presSchema, documentSchema);
-/**
- * This class models the view a document added to presentation will have in the presentation.
- * It involves some functionality for its buttons and options.
- */
-@observer
-export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDocument>(PresDocument) {
-    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(PresElementBox, fieldKey); }
-    _heightDisposer: IReactionDisposer | undefined;
-
-    @observable _dragging = false;
-    // these fields are conditionally computed fields on the layout document that take this document as a parameter
-    @computed get indexInPres() { return Number(this.lookupField("indexInPres")); }  // the index field is where this document is in the presBox display list (since this value is different for each presentation element, the value can't be stored on the layout template which is used by all display elements)
-    @computed get collapsedHeight() { return Number(this.lookupField("presCollapsedHeight")); } // the collapsed height changes depending on the state of the presBox.  We could store this on the presentation element template if it's used by only one presentation - but if it's shared by multiple, then this value must be looked up
-    @computed get presStatus() { return StrCast(this.lookupField("presStatus")); }
-    @computed get itemIndex() { return NumCast(this.lookupField("_itemIndex")); }
-    @computed get presBox() { return Cast(this.lookupField("presBox"), Doc, null); }
-    @computed get targetDoc() { return Cast(this.rootDoc.presentationTargetDoc, Doc, null) || this.rootDoc; }
-
-    componentDidMount() {
-        this.layoutDoc.hideLinkButton = true;
-        this._heightDisposer = reaction(() => [this.rootDoc.presExpandInlineButton, this.collapsedHeight],
-            params => this.layoutDoc._height = NumCast(params[1]) + (Number(params[0]) ? 100 : 0), { fireImmediately: true });
-    }
-    componentWillUnmount() {
-        this._heightDisposer?.();
-    }
-
-    /**
-     * Returns a local transformed coordinate array for given coordinates.
-     */
-    ScreenToLocalListTransform = (xCord: number, yCord: number) => [xCord, yCord];
-
-    @action
-    presExpandDocumentClick = () => {
-        this.rootDoc.presExpandInlineButton = !this.rootDoc.presExpandInlineButton;
-    }
-
-    embedHeight = (): number => 97;
-    // embedWidth = () => this.props.PanelWidth();
-    // embedHeight = () => Math.min(this.props.PanelWidth() - 20, this.props.PanelHeight() - this.collapsedHeight);
-    embedWidth = (): number => this.props.PanelWidth() - 35;
-    styleProvider = (doc: (Doc | undefined), props: Opt<DocumentViewProps>, property: string): any => {
-        if (property === StyleProp.Opacity) return 1;
-        return this.props.styleProvider?.(doc, props, property);
-    }
-    /**
-     * The function that is responsible for rendering a preview or not for this
-     * presentation element.
-     */
-    @computed get renderEmbeddedInline() {
-        return !this.rootDoc.presExpandInlineButton || !this.targetDoc ? (null) :
-            <div className="presItem-embedded" style={{ height: this.embedHeight(), width: this.embedWidth() }}>
-                <DocumentView
-                    Document={this.targetDoc}
-                    DataDoc={this.targetDoc[DataSym] !== this.targetDoc && this.targetDoc[DataSym]}
-                    styleProvider={this.styleProvider}
-                    layerProvider={this.props.layerProvider}
-                    docViewPath={returnEmptyDoclist}
-                    rootSelected={returnTrue}
-                    addDocument={returnFalse}
-                    removeDocument={returnFalse}
-                    isContentActive={this.props.isContentActive}
-                    addDocTab={returnFalse}
-                    pinToPres={returnFalse}
-                    PanelWidth={this.embedWidth}
-                    PanelHeight={this.embedHeight}
-                    ScreenToLocalTransform={Transform.Identity}
-                    moveDocument={this.props.moveDocument!}
-                    renderDepth={this.props.renderDepth + 1}
-                    focus={DocUtils.DefaultFocus}
-                    whenChildContentsActiveChanged={returnFalse}
-                    bringToFront={returnFalse}
-                    docFilters={this.props.docFilters}
-                    docRangeFilters={this.props.docRangeFilters}
-                    searchFilterDocs={this.props.searchFilterDocs}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined}
-                    hideLinkButton={true}
-                />
-                <div className="presItem-embeddedMask" />
-            </div>;
-    }
-
-    @computed get duration() {
-        let durationInS: number;
-        if (this.rootDoc.type === DocumentType.AUDIO || this.rootDoc.type === DocumentType.VID) { durationInS = NumCast(this.rootDoc.presEndTime) - NumCast(this.rootDoc.presStartTime); durationInS = Math.round(durationInS * 10) / 10; }
-        else if (this.rootDoc.presDuration) durationInS = NumCast(this.rootDoc.presDuration) / 1000;
-        else durationInS = 2;
-        return "D: " + durationInS + "s";
-    }
-
-    @computed get transition() {
-        let transitionInS: number;
-        if (this.rootDoc.presTransition) transitionInS = NumCast(this.rootDoc.presTransition) / 1000;
-        else transitionInS = 0.5;
-        return this.rootDoc.presMovement === PresMovement.Jump || this.rootDoc.presMovement === PresMovement.None ? (null) : "M: " + transitionInS + "s";
-    }
-
-    private _itemRef: React.RefObject<HTMLDivElement> = React.createRef();
-    private _dragRef: React.RefObject<HTMLDivElement> = React.createRef();
-    private _titleRef: React.RefObject<EditableView> = React.createRef();
-
-
-    @action
-    headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
-        const element = e.target as any;
-        e.stopPropagation();
-        e.preventDefault();
-        if (element && !(e.ctrlKey || e.metaKey)) {
-            if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
-                PresBox.Instance._selectedArray.size === 1 && PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false);
-                setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
-            } else {
-                setupMoveUpEvents(this, e, ((e: PointerEvent) => {
-                    PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, false);
-                    return this.startDrag(e);
-                }), emptyFunction, emptyFunction);
-            }
-        }
-    }
-
-    headerUp = (e: React.PointerEvent<HTMLDivElement>) => {
-        e.stopPropagation();
-        e.preventDefault();
-    }
-
-    startDrag = (e: PointerEvent) => {
-        const miniView: boolean = this.toolbarWidth <= 100;
-        const activeItem = this.rootDoc;
-        const dragArray = PresBox.Instance._dragArray;
-        const dragData = new DragManager.DocumentDragData(PresBox.Instance.sortArray());
-        const dragItem: HTMLElement[] = [];
-        if (dragArray.length === 1) {
-            const doc = dragArray[0];
-            doc.className = miniView ? "presItem-miniSlide" : "presItem-slide";
-            dragItem.push(doc);
-        } else if (dragArray.length >= 1) {
-            const doc = document.createElement('div');
-            doc.className = "presItem-multiDrag";
-            doc.innerText = "Move " + PresBox.Instance._selectedArray.size + " slides";
-            doc.style.position = 'absolute';
-            doc.style.top = (e.clientY) + 'px';
-            doc.style.left = (e.clientX - 50) + 'px';
-            dragItem.push(doc);
-        }
-
-        // const dropEvent = () => runInAction(() => this._dragging = false);
-        if (activeItem) {
-            DragManager.StartDocumentDrag(dragItem.map(ele => ele), dragData, e.clientX, e.clientY, undefined);
-            // runInAction(() => this._dragging = true);
-            return true;
-        }
-        return false;
-    }
-
-    onPointerOver = (e: any) => {
-        document.removeEventListener("pointermove", this.onPointerMove);
-        document.addEventListener("pointermove", this.onPointerMove);
-    }
-
-    onPointerMove = (e: PointerEvent) => {
-        const slide = this._itemRef.current!;
-        let dragIsPresItem: boolean = DragManager.docsBeingDragged.length > 0 ? true : false;
-        for (const doc of DragManager.docsBeingDragged) {
-            if (!doc.presentationTargetDoc) dragIsPresItem = false;
-        }
-        if (slide && dragIsPresItem) {
-            const rect = slide.getBoundingClientRect();
-            const y = e.clientY - rect.top;  //y position within the element.
-            const height = slide.clientHeight;
-            const halfLine = height / 2;
-            if (y <= halfLine) {
-                slide.style.borderTop = "solid 2px #5B9FDD";
-                slide.style.borderBottom = "0px";
-            } else if (y > halfLine) {
-                slide.style.borderTop = "0px";
-                slide.style.borderBottom = "solid 2px #5B9FDD";
-            }
-        }
-        document.removeEventListener("pointermove", this.onPointerMove);
-    }
-
-    onPointerLeave = (e: any) => {
-        this._itemRef.current!.style.borderTop = "0px";
-        this._itemRef.current!.style.borderBottom = "0px";
-        document.removeEventListener("pointermove", this.onPointerMove);
-    }
-
-    @action
-    toggleProperties = () => {
-        if (CurrentUserUtils.propertiesWidth < 5) {
-            action(() => (CurrentUserUtils.propertiesWidth = 250));
-        }
-    }
-
-    @undoBatch
-    removeItem = action((e: React.MouseEvent) => {
-        this.props.removeDocument?.(this.rootDoc);
-        if (PresBox.Instance._selectedArray.has(this.rootDoc)) {
-            PresBox.Instance._selectedArray.delete(this.rootDoc);
-        }
-        e.stopPropagation();
-    });
-
-    @undoBatch
-    @action
-    onSetValue = (value: string) => {
-        this.rootDoc.title = !value.trim().length ? "-untitled-" : value;
-        return true;
-    }
-
-    /**
-     * Method called for updating the view of the currently selected document
-     * 
-     * @param targetDoc 
-     * @param activeItem 
-     */
-    @undoBatch
-    @action
-    updateView = (targetDoc: Doc, activeItem: Doc) => {
-        if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.WEB || targetDoc.type === DocumentType.RTF) {
-            const scroll = targetDoc._scrollTop;
-            activeItem.presPinViewScroll = scroll;
-        } else if (targetDoc.type === DocumentType.VID) {
-            activeItem.presPinTimecode = targetDoc._currentTimecode;
-        } else if (targetDoc.type === DocumentType.COMPARISON) {
-            const clipWidth = targetDoc._clipWidth;
-            activeItem.presPinClipWidth = clipWidth;
-        } else {
-            const x = targetDoc._panX;
-            const y = targetDoc._panY;
-            const scale = targetDoc._viewScale;
-            activeItem.presPinViewX = x;
-            activeItem.presPinViewY = y;
-            activeItem.presPinViewScale = scale;
-        }
-    }
-
-    @computed
-    get toolbarWidth(): number {
-        const presBoxDocView = DocumentManager.Instance.getDocumentView(this.presBox);
-        let width: number = NumCast(this.presBox._width);
-        if (presBoxDocView) width = presBoxDocView.props.PanelWidth();
-        if (width === 0) width = 300;
-        return width;
-    }
-
-    @computed get mainItem() {
-        const isSelected: boolean = PresBox.Instance._selectedArray.has(this.rootDoc);
-        const toolbarWidth: number = this.toolbarWidth;
-        const showMore: boolean = this.toolbarWidth >= 300;
-        const miniView: boolean = this.toolbarWidth <= 110;
-        const presBox: Doc = this.presBox; //presBox
-        const presBoxColor: string = StrCast(presBox._backgroundColor);
-        const presColorBool: boolean = presBoxColor ? (presBoxColor !== "white" && presBoxColor !== "transparent") : false;
-        const targetDoc: Doc = this.targetDoc;
-        const activeItem: Doc = this.rootDoc;
-        return (
-            <div className={`presItem-container`}
-                key={this.props.Document[Id] + this.indexInPres}
-                ref={this._itemRef}
-                style={{
-                    backgroundColor: presColorBool ? isSelected ? "rgba(250,250,250,0.3)" : "transparent" : isSelected ? "#AEDDF8" : "transparent",
-                    opacity: this._dragging ? 0.3 : 1
-                }}
-                onClick={e => {
-                    e.stopPropagation();
-                    e.preventDefault();
-                    PresBox.Instance.modifierSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, !e.shiftKey && !e.ctrlKey && !e.metaKey, e.ctrlKey || e.metaKey, e.shiftKey);
-                }}
-                onDoubleClick={action(e => {
-                    this.toggleProperties();
-                    PresBox.Instance.regularSelect(this.rootDoc, this._itemRef.current!, this._dragRef.current!, true);
-                })}
-                onPointerOver={this.onPointerOver}
-                onPointerLeave={this.onPointerLeave}
-                onPointerDown={this.headerDown}
-                onPointerUp={this.headerUp}
-            >
-                {miniView ?
-                    // when width is LESS than 110 px 
-                    <div className={`presItem-miniSlide ${isSelected ? "active" : ""}`} ref={miniView ? this._dragRef : null}>
-                        {`${this.indexInPres + 1}.`}
-                    </div>
-                    :
-                    // when width is MORE than 110 px 
-                    <div className="presItem-number">
-                        {`${this.indexInPres + 1}.`}
-                    </div>}
-                {miniView ? (null) : <div ref={miniView ? null : this._dragRef} className={`presItem-slide ${isSelected ? "active" : ""}`}
-                    style={{
-                        backgroundColor: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor),
-                        boxShadow: presBoxColor && presBoxColor !== "white" && presBoxColor !== "transparent" ? isSelected ? "0 0 0px 1.5px" + presBoxColor : undefined : undefined
-                    }}>
-                    <div className="presItem-name" style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105, cursor: isSelected ? 'text' : 'grab' }}>
-                        <EditableView
-                            ref={this._titleRef}
-                            editing={!isSelected ? false : undefined}
-                            contents={activeItem.title}
-                            overflow={'ellipsis'}
-                            GetValue={() => StrCast(activeItem.title)}
-                            SetValue={this.onSetValue}
-                        />
-                    </div>
-                    <Tooltip title={<><div className="dash-tooltip">{"Movement speed"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.transition}</div></Tooltip>
-                    <Tooltip title={<><div className="dash-tooltip">{"Duration"}</div></>}><div className="presItem-time" style={{ display: showMore ? "block" : "none" }}>{this.duration}</div></Tooltip>
-                    <div className={"presItem-slideButtons"}>
-                        <Tooltip title={<><div className="dash-tooltip">{"Update view"}</div></>}>
-                            <div className="slideButton"
-                                onClick={() => this.updateView(targetDoc, activeItem)}
-                                style={{ fontWeight: 700, display: activeItem.presPinView ? "flex" : "none" }}>V</div>
-                        </Tooltip>
-                        {this.indexInPres === 0 ? (null) : <Tooltip title={<><div className="dash-tooltip">{activeItem.groupWithUp ? "Ungroup" : "Group with up"}</div></>}>
-                            <div className="slideButton"
-                                onClick={() => activeItem.groupWithUp = !activeItem.groupWithUp}
-                                style={{
-                                    zIndex: 1000 - this.indexInPres,
-                                    fontWeight: 700,
-                                    backgroundColor: activeItem.groupWithUp ? presColorBool ? presBoxColor : PresColor.DarkBlue : undefined,
-                                    height: activeItem.groupWithUp ? 53 : 18,
-                                    transform: activeItem.groupWithUp ? "translate(0, -17px)" : undefined
-                                }}>
-                                <div style={{ transform: activeItem.groupWithUp ? "rotate(180deg) translate(0, -17.5px)" : "rotate(0deg)" }}>
-                                    <FontAwesomeIcon icon={"arrow-up"} onPointerDown={e => e.stopPropagation()} />
-                                </div>
-                            </div>
-                        </Tooltip>}
-                        <Tooltip title={<><div className="dash-tooltip">{this.rootDoc.presExpandInlineButton ? "Minimize" : "Expand"}</div></>}><div className={"slideButton"} onClick={e => { e.stopPropagation(); this.presExpandDocumentClick(); }}>
-                            <FontAwesomeIcon icon={this.rootDoc.presExpandInlineButton ? "eye-slash" : "eye"} onPointerDown={e => e.stopPropagation()} />
-                        </div></Tooltip>
-                        <Tooltip title={<><div className="dash-tooltip">{"Remove from presentation"}</div></>}><div
-                            className={"slideButton"}
-                            onClick={this.removeItem}>
-                            <FontAwesomeIcon icon={"trash"} onPointerDown={e => e.stopPropagation()} />
-                        </div></Tooltip>
-                    </div>
-                    <div className="presItem-docName" style={{ maxWidth: showMore ? (toolbarWidth - 195) : toolbarWidth - 105 }}>{activeItem.presPinView ? (<><i>View of </i> {targetDoc.title}</>) : targetDoc.title}</div>
-                    {this.renderEmbeddedInline}
-                </div>}
-            </div >);
-    }
-
-    render() {
-        return !(this.rootDoc instanceof Doc) || this.targetDoc instanceof Promise ? (null) : this.mainItem;
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index 324b96dbd..e2d27d5a6 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -30,7 +30,7 @@
                 display: flex;
 
                 .topbar-dashboards {
-                    display: none;
+                    display: inline-flex;
                 }
 
                 .topbar-dashSelect {
@@ -46,12 +46,6 @@
                     }
                 }
             }
-
-            .topbar-lozenge-dashboard:hover {
-                .topbar-dashboards {
-                    display: inline-flex;
-                }
-            }
         }
 
         .topBar-icon {
@@ -85,7 +79,7 @@
             .topbar-lozenge {
                 height: 23;
                 font-size: 12;
-                color: black;
+                color: white;
                 font-family: 'Roboto';
                 font-weight: 400;
                 padding: 4px;
@@ -93,7 +87,7 @@
                 margin-right: 7px;
                 display: flex;
                 align-items: center;
-                border: black 1px solid;
+                border: white 1px solid;
 
                 .topbar-logoff {
                     border-radius: 3px;
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 79239d4ea..65da717f8 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -1,58 +1,67 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { observer } from "mobx-react";
 import * as React from 'react';
 import { Doc, DocListCast } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { StrCast } from '../../../fields/Types';
 import { Utils } from '../../../Utils';
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { ColorScheme, SettingsManager } from "../../util/SettingsManager";
+import { SettingsManager } from "../../util/SettingsManager";
 import { undoBatch } from "../../util/UndoManager";
+import { Borders, Colors } from "../global/globalEnums";
 import "./TopBar.scss";
-import { Colors, Borders } from "../global/globalEnums";
 
-export const TopBar = () => {
-
-    const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
-    return (
-        <div style={{ pointerEvents: "all" }} className="topbar-container">
-            <div className="topbar-bar" style={{ background: Doc.UserDoc().colorScheme === ColorScheme.Dark ? Colors.DARK_GRAY : Colors.LIGHT_GRAY, borderBottom: Borders.STANDARD }}>
-                <div className="topbar-center" >
-                    <div className="topbar-lozenge-dashboard">
-                        <select className="topbar-dashSelect" onChange={e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)])}
-                            value={myDashboards.indexOf(CurrentUserUtils.ActiveDashboard)}
-                            style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
-                            {myDashboards.map((dash, i) => <option key={dash[Id]} value={i}> {StrCast(dash.title)} </option>)}
-                        </select>
-                        <div className="topbar-dashboards">
-                            <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}
-                                style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
-                                <FontAwesomeIcon icon="plus"></FontAwesomeIcon>
-                            </div>
-                            <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.snapshotDashboard(Doc.UserDoc()))}
-                                style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
-                                <FontAwesomeIcon icon="camera"></FontAwesomeIcon>
+/**
+ * REACT TYPE: FUNCTIONAL
+ * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
+ * and settings and help buttons. Future scope for this bar is to include the collaborators that are on the same Dashboard. 
+ */
+@observer
+export class TopBar extends React.Component {
+    render() {
+        const myDashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
+        return (
+            //TODO:glr Add support for light / dark mode
+            <div style={{ pointerEvents: "all" }} className="topbar-container">
+                <div className="topbar-bar" style={{ background: Colors.DARK_GRAY, borderBottom: Borders.STANDARD }}>
+                    <div className="topbar-center" >
+                        <div className="topbar-lozenge-dashboard">
+                            <select className="topbar-dashSelect" onChange={e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)])}
+                                value={myDashboards.indexOf(CurrentUserUtils.ActiveDashboard)}
+                                style={{ color: Colors.WHITE }}>
+                                {myDashboards.map((dash, i) => <option key={dash[Id]} value={i}> {StrCast(dash.title)} </option>)}
+                            </select>
+                            <div className="topbar-dashboards">
+                                <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}
+                                    style={{ color: Colors.WHITE }}>
+                                    <FontAwesomeIcon icon="plus"></FontAwesomeIcon>
+                                </div>
+                                <div className="topbar-icon" onClick={undoBatch(() => CurrentUserUtils.snapshotDashboard(Doc.UserDoc()))}
+                                    style={{ color: Colors.WHITE }}>
+                                    <FontAwesomeIcon icon="camera"></FontAwesomeIcon>
+                                </div>
                             </div>
                         </div>
                     </div>
-                </div>
-                <div className="topbar-right" >
-                    <div className="topbar-icon"
-                        style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
-                        <FontAwesomeIcon icon="question-circle"></FontAwesomeIcon>
-                    </div>
-                    <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}
-                        style={{ color: Doc.UserDoc().colorScheme === ColorScheme.Dark ? "white" : "black" }}>
-                        <FontAwesomeIcon icon="cog"></FontAwesomeIcon>
-                    </div>
-                    <div className="topbar-lozenge-user">
-                        {`${Doc.CurrentUserEmail}`}
-                        <div className="topbar-logoff" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
-                            Logoff
+                    <div className="topbar-right" >
+                        <div className="topbar-icon"
+                            style={{ color: Colors.WHITE }}>
+                            <FontAwesomeIcon icon="question-circle"></FontAwesomeIcon>
+                        </div>
+                        <div className="topbar-icon" onClick={() => SettingsManager.Instance.open()}
+                            style={{ color: Colors.WHITE }}>
+                            <FontAwesomeIcon icon="cog"></FontAwesomeIcon>
+                        </div>
+                        <div className="topbar-lozenge-user">
+                            {`${Doc.CurrentUserEmail}`}
+                            <div className="topbar-logoff" onClick={() => window.location.assign(Utils.prepend("/logout"))}>
+                                Logoff
+                        </div>
                         </div>
                     </div>
-                </div>
 
+                </div >
             </div >
-        </div >
-    );
+        );
+    }
 }
\ No newline at end of file
diff --git a/tslint.json b/tslint.json
index 0056f4266..83255a798 100644
--- a/tslint.json
+++ b/tslint.json
@@ -1,6 +1,9 @@
 {
     "linterOptions": {
-        "exclude": ["./src/client/northstar/**", "**/*.js"]
+        "exclude": [
+            "./src/client/northstar/**",
+            "**/*.js"
+        ]
     },
     "rules": {
         "no-return-await": true,
@@ -23,41 +26,7 @@
         ],
         "no-tautology-expression": true,
         "unnecessary-constructor": true
-        // "trailing-comma": [
-        //     true,
-        //     {
-        //         "multiline": "always",
-        //         "singleline": "never"
-        //     }
-        // ],
-        // "ordered-imports": true
-        // "quotemark": [
-        //     true,
-        //     "double",
-        //     "jsx-double",
-        //     "avoid-template",
-        //     "avoid-escape"
-        // ],
-        // "object-literal-shorthand": true,
-        // "object-literal-sort-keys": true,
-        // "align": [
-        //     true,
-        //     "parameters",
-        //     "arguments",
-        //     "statements",
-        //     "members",
-        //     "elements"
-        // ],
-        // "no-void-expression": [
-        //     true,
-        //     "ignore-arrow-function-shorthand"
-        // ],
-        // "no-non-null-assertion": true,
-        // "no-var-keyword": true,
-        // "no-var-requires": true,
     },
     "defaultSeverity": "warning",
-    "jsRules": {
-
-    }
+    "jsRules": {}
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 2ec093982c06965086326df73d365e1b54f6a2a2 Mon Sep 17 00:00:00 2001
From: dg314 <david_grossman@brown.edu>
Date: Wed, 4 Aug 2021 03:19:16 -0400
Subject: search panel updates

---
 src/client/util/CurrentUserUtils.ts    | 27 ++++++-----
 src/client/views/GlobalKeyHandler.ts   |  7 ++-
 src/client/views/MainView.tsx          | 37 --------------
 src/client/views/search/SearchBox.scss | 19 ++++++--
 src/client/views/search/SearchBox.tsx  | 89 +++++++++++++++++-----------------
 5 files changed, 81 insertions(+), 98 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 31384da3b..734b96b1e 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -46,6 +46,7 @@ export class CurrentUserUtils {
     //TODO tfs: these should be temporary...
     private static mainDocId: string | undefined;
 
+    public static searchBtn: Doc;
     public static get id() { return this.curr_id; }
     public static get MainDocId() { return this.mainDocId; }
     public static set MainDocId(id: string | undefined) { this.mainDocId = id; }
@@ -533,15 +534,6 @@ export class CurrentUserUtils {
         ];
     }
 
-    /*static setupSearchPanel(doc: Doc) {
-        if (doc.mySearchPanelDoc === undefined) {
-            doc.mySearchPanelDoc = new PrefetchProxy(Docs.Create.SearchDocument({
-                _width: 500, _height: 300, backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
-                childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
-            })) as any as Doc;
-        }
-    }*/
-
     static async setupMenuPanel(doc: Doc, sharingDocumentId: string, linkDatabaseId: string) {
         if (doc.menuStack === undefined) {
             await this.setupSharingSidebar(doc, sharingDocumentId, linkDatabaseId);  // sets up the right sidebar collection for mobile upload documents and sharing
@@ -562,10 +554,23 @@ export class CurrentUserUtils {
                     _height: 60,
                     watchedDocuments,
                     onClick: ScriptField.MakeScript(click, { scriptContext: "any" })
-                }));
+                })
+            );
+
+            menuBtns.forEach(menuBtn => {
+                if (menuBtn.title == "Search") {
+                    this.searchBtn = menuBtn;
+                }
+            });
             // hack -- last button is assumed to be the userDoc
             menuBtns[menuBtns.length - 1].hidden = ComputedField.MakeFunction("IsNoviceMode()");
 
+            menuBtns.forEach(menuBtn => {
+                if (menuBtn.title == "Search") {
+                    doc.searchBtn = menuBtn
+                }
+            })
+
             doc.menuStack = new PrefetchProxy(Docs.Create.StackingDocument(menuBtns, {
                 title: "menuItemPanel",
                 childDropAction: "alias",
@@ -950,7 +955,7 @@ export class CurrentUserUtils {
         if (doc.mySearchPanel === undefined) {
             doc.mySearchPanel = new PrefetchProxy(Docs.Create.SearchDocument({
                 backgroundColor: "dimGray", ignoreClick: true, _searchDoc: true,
-                childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "sidebar search stack", system: true
+                childDropAction: "alias", _lockedPosition: true, _viewType: CollectionViewType.Schema, title: "Search Sidebar", system: true
             })) as any as Doc;
         }
     }
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index d92cba3eb..2a3cb36c7 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -27,7 +27,6 @@ import { LightboxView } from "./LightboxView";
 import { MainView } from "./MainView";
 import { DocumentLinksButton } from "./nodes/DocumentLinksButton";
 import { AnchorMenu } from "./pdf/AnchorMenu";
-import { SearchBox } from "./search/SearchBox";
 import { CurrentUserUtils } from "../util/CurrentUserUtils";
 import { SettingsManager } from "../util/SettingsManager";
 
@@ -225,7 +224,11 @@ export class KeyManager {
                 PromiseValue(Cast(Doc.UserDoc()["tabs-button-tools"], Doc)).then(pv => pv && (pv.onClick as ScriptField).script.run({ this: pv }));
                 break;
             case "f":
-                SearchBox.Instance.enter(undefined);
+                const searchBtn = Doc.UserDoc().searchBtn as Doc;
+
+                if (searchBtn) {
+                    MainView.Instance.selectMenu(searchBtn);
+                }
                 break;
             case "o":
                 const target = SelectionManager.Views()[0];
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 0d957518b..35222e91f 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -387,9 +387,6 @@ export class MainView extends React.Component {
                 case "Settings":
                     SettingsManager.Instance.open();
                     break;
-                case "Catalog":
-                    SearchBox.Instance.enter(undefined);
-                    break;
                 case "Help":
                     break;
                 default:
@@ -522,40 +519,6 @@ export class MainView extends React.Component {
         </svg>;
     }
 
-    /*@computed get search() {
-        TraceMobx();
-        return <div className="mainView-searchPanel">
-            <SearchBox Document={CurrentUserUtils.MySearchPanelDoc}
-                DataDoc={CurrentUserUtils.MySearchPanelDoc}
-                fieldKey="data"
-                dropAction="move"
-                isSelected={returnTrue}
-                isContentActive={returnTrue}
-                select={returnTrue}
-                setHeight={returnFalse}
-                addDocument={undefined}
-                addDocTab={this.addDocTabFunc}
-                pinToPres={emptyFunction}
-                rootSelected={returnTrue}
-                styleProvider={DefaultStyleProvider}
-                layerProvider={undefined}
-                removeDocument={undefined}
-                ScreenToLocalTransform={Transform.Identity}
-                PanelWidth={this.getPWidth}
-                PanelHeight={this.getPHeight}
-                renderDepth={0}
-                focus={DocUtils.DefaultFocus}
-                docViewPath={returnEmptyDoclist}
-                whenChildContentsActiveChanged={emptyFunction}
-                bringToFront={emptyFunction}
-                docFilters={returnEmptyFilter}
-                docRangeFilters={returnEmptyFilter}
-                searchFilterDocs={returnEmptyDoclist}
-                ContainingCollectionView={undefined}
-                ContainingCollectionDoc={undefined} />
-        </div>;
-    }*/
-
     @computed get invisibleWebBox() { // see note under the makeLink method in HypothesisUtils.ts
         return !DocumentLinksButton.invisibleWebDoc ? null :
             <div className="mainView-invisibleWebRef" ref={DocumentLinksButton.invisibleWebRef}>
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index f8e994da7..e4d1ac6a3 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -22,17 +22,18 @@
 
         .searchBox-type {
             display: block;
-            width: 50px;
+            width: 55px;
             outline: none;
             padding: 1px 5px 1px 5px;
             color: black;
             height: 25px;
             border: 1px solid black;
+            border-right: 0px;
         }
 
         .searchBox-input {
             display: block;
-            width: calc(100% - 50px);
+            width: calc(100% - 55px);
             outline: none;
             padding: 1px 5px 1px 5px;
             color: black;
@@ -74,10 +75,20 @@
                     background: gray;
                 }
 
-                .titletitle {
+                .searchBox-result-title {
                     display: relative;
                     float: left;
-                    left: 50px;
+                    width: calc(100% - 60px);
+                    text-align: left;
+                }
+
+                .searchBox-result-type {
+                    font-size: 12px;
+                    display: relative;
+                    float: right;
+                    width: 60px;
+                    text-align: right;
+                    color: #333;
                 }
             }
         }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 374a754bf..3cbb4b3b1 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -35,29 +35,30 @@ export const searchSchema = createSchema({ Document: Doc });
 type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
 const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
 
+const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
+
 @observer
 export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
     public static Instance: SearchBox;
 
-    private _allIcons: string[] = [DocumentType.INK, DocumentType.AUDIO, DocumentType.COL, DocumentType.IMG, DocumentType.LINK, DocumentType.PDF, DocumentType.RTF, DocumentType.VID, DocumentType.WEB];
     private _resultsSet = new Map<Doc, number>();
     private _inputRef = React.createRef<HTMLInputElement>();
-    private _disposers: { [name: string]: IReactionDisposer } = {};
-    private _blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
 
     @observable _searchString = "";
     @observable _docTypeString = "all";
-    @observable _icons: string[] = this._allIcons;
     @observable _results: [Doc, string[], string[]][] = [];
     @observable _selectedResult: Doc | undefined = undefined;
     @observable _deletedDocsStatus: boolean = false;
     @observable _onlyAliases: boolean = true;
-    @computed get filter() { return this._results?.length && (this.currentSelectedCollection?.props.Document._searchFilterDocs || this.currentSelectedCollection?.props.Document._docFilters); }
 
     constructor(props: any) {
         super(props);
         SearchBox.Instance = this;
+        this._searchString = "reset_search";
+        this.submitSearch();
+        this._searchString = "";
+        this.submitSearch();
     }
 
     componentDidMount = action(() => {
@@ -67,11 +68,9 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     });
 
     componentWillUnmount() {
-        Object.values(this._disposers).forEach(disposer => disposer?.());
+        this.resetSearch;
     }
 
-    @computed get currentSelectedCollection() { return CollectionDockingView.Instance; }
-
     onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
         this._searchString = e.target.value;
         this.submitSearch();
@@ -79,32 +78,13 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
     onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
         this._docTypeString = e.target.value;
-        this.submitSearch();
     });
 
-    /*enter = action((e: React.KeyboardEvent | undefined) => {
-        if (!e || e.key === "Enter") {
-            this.submitSearch();
-        }
-    });*/
-
     onResultClick = action((doc: Doc) => {
         this.selectElement(doc);
         this._selectedResult = doc;
     });
 
-    @action
-    filterDocsByType(docs: Doc[]) {
-        const finalDocs: Doc[] = [];
-        docs.forEach(doc => {
-            const layoutresult = StrCast(doc.type, "string") as DocumentType;
-            if (layoutresult && !this._blockedTypes.includes(layoutresult) && this._icons.includes(layoutresult)) {
-                finalDocs.push(doc);
-            }
-        });
-        return finalDocs;
-    }
-
     static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
         let newarray: Doc[] = [];
         while (docs.length > 0) {
@@ -120,23 +100,39 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         }
     }
 
+    static formatType(type: String): String {
+        if (type == "pdf") {
+            return "PDF";
+        }
+        else if (type == "image") {
+            return "Img";
+        }
+
+        return type.charAt(0).toUpperCase() + type.substring(1, 3);
+    }
+
     @action
     searchCollection(query: string) {
-        const selectedCollection = this.currentSelectedCollection;//SelectionManager.SelectedDocuments()[0];
+        const selectedCollection = CollectionDockingView.Instance;
+        const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
         query = query.toLowerCase();
 
+        this._results = []
+
         if (selectedCollection !== undefined) {
-            // this._currentSelectedCollection = selectedCollection;
             const docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]);
-            const found: [Doc, string[], string[]][] = [];
             SearchBox.foreachRecursiveDoc(docs, (doc: Doc) => {
-                const hlights = new Set<string>();
-                SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
-                Array.from(hlights.keys()).length > 0 && found.push([doc, Array.from(hlights.keys()), []]);
+                const dtype = StrCast(doc.type, "string") as DocumentType;
+                if (dtype && !blockedTypes.includes(dtype)) {
+                    const hlights = new Set<string>();
+                    SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
+                    Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys()), []]);
+                }
             });
-
-            this._results = found;
         }
+
+        this._results = Array.from(new Set(this._results))
+        this._selectedResult = undefined
     }
 
     static documentKeys(doc: Doc) {
@@ -155,7 +151,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     submitSearch = async () => {
         this.resetSearch();
 
-        this.dataDoc[this.fieldKey] = new List<Doc>([]);
+        //this.dataDoc[this.fieldKey] = new List<Doc>([]);
         let query = StrCast(this._searchString);
         Doc.SetSearchQuery(query);
         this._results = [];
@@ -169,6 +165,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     resetSearch = action(() => {
         this._results.forEach(result => {
             Doc.UnBrushDoc(result[0]);
+            Doc.UnHighlightDoc(result[0]);
             Doc.ClearSearchMatches();
         });
     });
@@ -178,6 +175,8 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
     }
 
     render() {
+        var validResults = 0;
+
         const results = this._results.map(result => {
             var className = "searchBox-results-scroll-view-result";
 
@@ -186,28 +185,30 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             }
 
             if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
-                return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="titletitle">{result[0].title}</div></div>)
+                validResults++;
+                return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="searchBox-result-title">{result[0].title}</div><div className="searchBox-result-type">{SearchBox.formatType(StrCast(result[0].type))}</div></div>)
             }
 
             return null;
         })
 
-        results.filter(result => result)
+        results.filter(result => result);
+
+        const selectOptions = selectValues.map(value => {
+            return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
+        })
 
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
                 <div className="searchBox-bar">
                     <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
-                        <option value="all">All</option>
-                        <option value="rtf">Text</option>
-                        <option value="img">Image</option>
-                        <option value="pdf">PDF</option>
+                        {selectOptions}
                     </select>
-                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" ref={this._inputRef} className="searchBox-input" />
+                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" ref={this._inputRef} />
                 </div >
                 <div className="searchBox-results-container">
                     <div className="searchBox-results-count">
-                        {`${results.length}` + " result" + (results.length == 1 ? "" : "s")}
+                        {`${validResults}` + " result" + (validResults == 1 ? "" : "s")}
                     </div>
                     <div className="searchBox-results-scroll-view">
                         {results}
-- 
cgit v1.2.3-70-g09d2


From d511c116330c3a125e6557aa5be70392aca4914b Mon Sep 17 00:00:00 2001
From: dg314 <david_grossman@brown.edu>
Date: Thu, 5 Aug 2021 16:38:00 -0400
Subject: comments

---
 src/client/views/MainView.tsx                      |   6 -
 .../views/collections/CollectionSchemaHeaders.tsx  |   2 +-
 src/client/views/search/SearchBox.scss             |  22 +-
 src/client/views/search/SearchBox.tsx              | 382 +++++++++------------
 4 files changed, 177 insertions(+), 235 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 35222e91f..97c88930e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -178,12 +178,6 @@ export class MainView extends React.Component {
         const targets = document.elementsFromPoint(e.x, e.y);
         if (targets.length) {
             const targClass = targets[0].className.toString();
-            /*if (SearchBox.Instance._resultsOpen) {
-                const check = targets.some((thing) =>
-                (thing.className === "collectionSchemaView-searchContainer" || (thing as any)?.dataset.icon === "filter" ||
-                    thing.className === "collectionSchema-header-menuOptions"));
-                !check && SearchBox.Instance.resetSearch(true);
-            }*/
             !targClass.includes("contextMenu") && ContextMenu.Instance.closeMenu();
             !["timeline-menu-desc", "timeline-menu-item", "timeline-menu-input"].includes(targClass) && TimelineMenu.Instance.closeMenu();
         }
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 3b52e6408..c98dcd1d0 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -424,7 +424,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                         e.target.checked === true ? Doc.setDocFilter(this.props.Document, this._key, key, "check") : Doc.setDocFilter(this.props.Document, this._key, key, "remove");
                         e.target.checked === true ? this.closeResultsVisibility = "contents" : console.log("");
                         e.target.checked === true ? this.props.col.setColor("green") : this.updateFilter();
-                        e.target.checked === true && SearchBox.Instance.filter === true ? Doc.setDocFilter(docs[0], this._key, key, "check") : Doc.setDocFilter(docs[0], this._key, key, "remove");
+                        e.target.checked === true ? Doc.setDocFilter(docs[0], this._key, key, "check") : Doc.setDocFilter(docs[0], this._key, key, "remove");
                     }}
                     checked={bool}
                 />
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index e4d1ac6a3..e7526dac8 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -66,13 +66,13 @@
                 display: inline-block;
                 vertical-align: middle;
                 width: 100%;
-                height: 40px;
+                height: 50px;
                 cursor: pointer;
                 font-size: 15px;
-                padding: 10px;
+                padding: 11px;
 
                 &.searchBox-results-scroll-view-result-selected {
-                    background: gray;
+                    background: #999;
                 }
 
                 .searchBox-result-title {
@@ -84,11 +84,25 @@
 
                 .searchBox-result-type {
                     font-size: 12px;
+                    margin-top: 6px;
                     display: relative;
                     float: right;
                     width: 60px;
                     text-align: right;
-                    color: #333;
+                    color: #222;
+                }
+
+                .searchBox-result-keys {
+                    font-size: 10px;
+                    margin-top: 1px;
+                    display: relative;
+                    float: left;
+                    width: 100%;
+                    text-align: left;
+                    color: #555;
+                    white-space: nowrap;
+                    overflow: hidden;
+                    text-overflow: ellipsis;
                 }
             }
         }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 3cbb4b3b1..8ef09aa56 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -27,66 +27,105 @@ import { undoBatch } from "../../util/UndoManager";
 import { DocServer } from "../../DocServer";
 import { MainView } from "../MainView";
 import { DocumentManager } from "../../util/DocumentManager";
-import { CollectionSchemaBooleanCell } from "../collections/CollectionSchemaCells";
-import { transpileModule } from "typescript";
 
 export const searchSchema = createSchema({ Document: Doc });
 
 type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
 const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
 
-const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
-
+/**
+ * This is the SearchBox component. It represents the search box input and results in
+ * the search panel on the left side of the screen.
+ */
 @observer
 export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
     public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
     public static Instance: SearchBox;
 
-    private _resultsSet = new Map<Doc, number>();
     private _inputRef = React.createRef<HTMLInputElement>();
+    private _selectedCollection = CollectionDockingView.Instance;
 
     @observable _searchString = "";
     @observable _docTypeString = "all";
-    @observable _results: [Doc, string[], string[]][] = [];
+    @observable _results: [Doc, string[]][] = [];
     @observable _selectedResult: Doc | undefined = undefined;
     @observable _deletedDocsStatus: boolean = false;
     @observable _onlyAliases: boolean = true;
 
+    /**
+     * This is the constructor for the SearchBox class.
+     */
     constructor(props: any) {
         super(props);
         SearchBox.Instance = this;
-        this._searchString = "reset_search";
-        this.submitSearch();
-        this._searchString = "";
-        this.submitSearch();
     }
 
+    /** 
+     * This method is called when the SearchBox component is first mounted. When the user opens
+     * the search panel, the search input box is automatically selected. This allows the user to
+     * type in the search input box immediately, without needing clicking on it first.
+     */
     componentDidMount = action(() => {
         if (this._inputRef.current) {
             this._inputRef.current.focus();
         }
     });
 
+    /**
+     * This method is called when the SearchBox component is about to be unmounted. When the user
+     * closes the search panel, the search and its results are reset.
+     */
     componentWillUnmount() {
-        this.resetSearch;
+        this.resetSearch();
     }
 
+    /**
+     * This method is called when the text in the search input box is modified by the user. The
+     * _searchString is updated to the new value of the text in the input box and submitSearch
+     * is called to update the search results accordingly.
+     * 
+     * (Note: There is no longer a need to press enter to submit a search. Any update to the input
+     * causes a search to be submitted automatically.)
+     */
     onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
         this._searchString = e.target.value;
         this.submitSearch();
     });
 
+    /**
+     * This method is called when the option in the select drop-down menu is changed. The
+     * _docTypeString is updated to the new value of the option in the drop-down menu. This
+     * is used to filter the results of the search to documents of a specific type.
+     * 
+     * (Note: This doesn't affect the results array, so there is no need to submit a new
+     * search here. The results of the search on the _searchString query are simply filtered
+     * by type directly before rendering them.)
+     */
     onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
         this._docTypeString = e.target.value;
     });
 
+    /**
+     * @param {Doc} doc - doc of the search result that has been clicked on
+     *
+     * This method is called when the user clicks on a search result. The _selectedResult is
+     * updated accordingly and the doc is highlighted with the selectElement method.
+     */
     onResultClick = action((doc: Doc) => {
         this.selectElement(doc);
         this._selectedResult = doc;
     });
 
-    static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
+    /**
+     * @param {Doc[]} docs - docs to be searched through recursively
+     * @param {number, Doc => void} func - function to be called on each doc
+     *
+     * This method iterates through an array of docs and all docs within those docs, calling
+     * the function func on each doc.
+     */
+    static foreachRecursiveDoc(docs: Doc[], func: (depth: number, doc: Doc) => void) {
         let newarray: Doc[] = [];
+        var depth = 0;
         while (docs.length > 0) {
             newarray = [];
             docs.filter(d => d).forEach(d => {
@@ -94,12 +133,45 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
                 const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
                 const data = d[annos ? fieldKey + "-annotations" : fieldKey];
                 data && newarray.push(...DocListCast(data));
-                func(d);
+                func(depth, d);
             });
             docs = newarray;
+            depth++;
         }
     }
 
+    /**
+     * @param {Doc[]} docs - docs to be searched through recursively
+     * @param {number, Doc => void} func - function to be called on each doc
+     *
+     * This method iterates asynchronously through an array of docs and all docs within those
+     * docs, calling the function func on each doc.
+     */
+    static async foreachRecursiveDocAsync(docs: Doc[], func: (depth: number, doc: Doc) => void) {
+        let newarray: Doc[] = [];
+        var depth = 0;
+        while (docs.length > 0) {
+            newarray = [];
+            await Promise.all(docs.filter(d => d).map(async d => {
+                const fieldKey = Doc.LayoutFieldKey(d);
+                const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
+                const data = d[annos ? fieldKey + "-annotations" : fieldKey];
+                const docs = await DocListCastAsync(data);
+                docs && newarray.push(...docs);
+                func(depth, d);
+            }));
+            docs = newarray;
+            depth++;
+        }
+    }
+
+    /**
+     * @param {String} type - string representing the type of a doc
+     *
+     * This method converts a doc type string of any length to a 3-letter doc type string in
+     * which the first letter is capitalized. This is used when displaying the type on the
+     * right side of each search result.
+     */
     static formatType(type: String): String {
         if (type == "pdf") {
             return "PDF";
@@ -111,57 +183,75 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         return type.charAt(0).toUpperCase() + type.substring(1, 3);
     }
 
+    /**
+     * @param {String} query - search query string
+     *
+     * This method searches the CollectionDockingView instance for a certain query and puts
+     * the matching results in the results array. Docs are considered to be matching results
+     * when the query is a substring of many different pieces of its metadata (title, text,
+     * author, etc).
+     */
     @action
     searchCollection(query: string) {
-        const selectedCollection = CollectionDockingView.Instance;
         const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
+        const blockedKeys = ["x", "y", "proto", "width", "autoHeight", "acl-Override", "acl-Public", "context", "zIndex", "height", "text-scrollHeight", "text-height", "cloneFieldFilter", "isPrototype", "text-annotations",
+            "dragFactory-count", "text-noTemplate", "aliases", "system", "layoutKey", "baseProto", "xMargin", "yMargin", "links", "layout", "layout_keyValue", "fitWidth", "viewType", "title-custom",
+            "panX", "panY", "viewScale"]
         query = query.toLowerCase();
 
         this._results = []
+        this._selectedResult = undefined
 
-        if (selectedCollection !== undefined) {
-            const docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]);
-            SearchBox.foreachRecursiveDoc(docs, (doc: Doc) => {
+        if (this._selectedCollection !== undefined) {
+            const docs = DocListCast(this._selectedCollection.dataDoc[Doc.LayoutFieldKey(this._selectedCollection.dataDoc)]);
+            const docIDs: String[] = []
+            SearchBox.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
                 const dtype = StrCast(doc.type, "string") as DocumentType;
-                if (dtype && !blockedTypes.includes(dtype)) {
+                if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth > 0) {
                     const hlights = new Set<string>();
                     SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
-                    Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys()), []]);
+                    blockedKeys.forEach(key => {
+                        hlights.delete(key);
+                    })
+                    Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys())]);
                 }
+                docIDs.push(doc[Id])
             });
         }
-
-        this._results = Array.from(new Set(this._results))
-        this._selectedResult = undefined
     }
 
+    /**
+     * @param {Doc} doc - doc for which keys are returned
+     * 
+     * This method returns a list of a document doc's keys.
+     */
     static documentKeys(doc: Doc) {
         const keys: { [key: string]: boolean } = {};
-        // bcz: ugh.  this is untracked since otherwise a large collection of documents will blast the server for all their fields.
-        //  then as each document's fields come back, we update the documents _proxies.  Each time we do this, the whole schema will be
-        //  invalidated and re-rendered.   This workaround will inquire all of the document fields before the options button is clicked.
-        //  then by the time the options button is clicked, all of the fields should be in place.  If a new field is added while this menu
-        //  is displayed (unlikely) it won't show up until something else changes.
-        //TODO Types
         Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false));
         return Array.from(Object.keys(keys));
     }
 
+    /**
+     * This method submits a search with the _searchString as its query and updates
+     * the results array accordingly.
+     */
     @action
     submitSearch = async () => {
         this.resetSearch();
 
-        //this.dataDoc[this.fieldKey] = new List<Doc>([]);
         let query = StrCast(this._searchString);
         Doc.SetSearchQuery(query);
         this._results = [];
-        this._resultsSet.clear();
 
         if (query) {
             this.searchCollection(query);
         }
     }
 
+    /**
+     * This method resets the search by iterating through each result and removing all
+     * brushes and highlights. All search matches are cleared as well.
+     */
     resetSearch = action(() => {
         this._results.forEach(result => {
             Doc.UnBrushDoc(result[0]);
@@ -170,10 +260,32 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
         });
     });
 
+    /**
+     * @param {Doc} doc - doc to be selected
+     * 
+     * This method selects a doc by either jumping to it (centering/zooming in on it)
+     * or opening it in a new tab.
+     */
     selectElement = async (doc: Doc) => {
-        await DocumentManager.Instance.jumpToDocument(doc, true); // documents open in new tab instead of on right    
+        await DocumentManager.Instance.jumpToDocument(doc, true);
+    }
+
+    /**
+     * This method returns a JSX list of the options in the select drop-down menu, which
+     * is used to filter the types of documents that appear in the search results.
+     */
+    @computed
+    public get selectOptions() {
+        const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
+
+        return selectValues.map(value => {
+            return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
+        })
     }
 
+    /**
+     * This method renders the search input box, select drop-down menu, and search results.
+     */
     render() {
         var validResults = 0;
 
@@ -186,7 +298,19 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
             if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
                 validResults++;
-                return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="searchBox-result-title">{result[0].title}</div><div className="searchBox-result-type">{SearchBox.formatType(StrCast(result[0].type))}</div></div>)
+                return (
+                    <div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}>
+                        <div className="searchBox-result-title">
+                            {result[0].title}
+                        </div>
+                        <div className="searchBox-result-type">
+                            {SearchBox.formatType(StrCast(result[0].type))}
+                        </div>
+                        <div className="searchBox-result-keys">
+                            {result[1].join(", ")}
+                        </div>
+                    </div>
+                )
             }
 
             return null;
@@ -194,15 +318,11 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
 
         results.filter(result => result);
 
-        const selectOptions = selectValues.map(value => {
-            return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
-        })
-
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
                 <div className="searchBox-bar">
                     <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
-                        {selectOptions}
+                        {this.selectOptions}
                     </select>
                     <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" ref={this._inputRef} />
                 </div >
@@ -217,190 +337,4 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
             </div >
         );
     }
-}
-
-
-
-/*
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { Tooltip } from '@material-ui/core';
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Doc, DocListCast, Field, Opt, DocListCastAsync, DataSym, HeightSym, FieldsSym } from '../../../fields/Doc';
-import { documentSchema } from "../../../fields/documentSchemas";
-import { Copy, Id, ToString } from '../../../fields/FieldSymbols';
-import { List } from '../../../fields/List';
-import { createSchema, listSpec, makeInterface } from '../../../fields/Schema';
-import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
-import { DocumentType } from "../../documents/DocumentTypes";
-import { CurrentUserUtils } from "../../util/CurrentUserUtils";
-import { SetupDrag } from '../../util/DragManager';
-import { SearchUtil } from '../../util/SearchUtil';
-import { Transform } from '../../util/Transform';
-import { CollectionDockingView } from "../collections/CollectionDockingView";
-import { CollectionSchemaView, ColumnType } from "../collections/CollectionSchemaView";
-import { CollectionViewType } from '../collections/CollectionView';
-import { ViewBoxBaseComponent } from "../DocComponent";
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
-import "./SearchBox.scss";
-import { undoBatch } from "../../util/UndoManager";
-import { DocServer } from "../../DocServer";
-import { MainView } from "../MainView";
-import { SelectionManager } from "../../util/SelectionManager";
-import { CollectionSchemaBooleanCell } from "../collections/CollectionSchemaCells";
-import { transpileModule } from "typescript";
-import { DocumentManager } from "../../util/DocumentManager";
-
-export const searchSchema = createSchema({ Document: Doc });
-
-type SearchBoxDocument = makeInterface<[typeof documentSchema, typeof searchSchema]>;
-const SearchBoxDocument = makeInterface(documentSchema, searchSchema);
-
-@observer
-export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDocument>(SearchBoxDocument) {
-    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(SearchBox, fieldKey); }
-    public static Instance: SearchBox;
-
-    @observable _searchString = "";
-    @observable _docTypeString = "all";
-    @observable _results: [Doc, string[], string[]][] = [];
-    @observable _selectedResult: Doc | undefined = undefined;
-    @observable _deletedDocsStatus: boolean = false;
-    @observable _onlyAliases: boolean = true;
-
-    constructor(props: any) {
-        super(props);
-        SearchBox.Instance = this;
-    }
-
-    onInputChange = action((e: React.ChangeEvent<HTMLInputElement>) => {
-        this._searchString = e.target.value;
-        this.submitSearch();
-    });
-
-    onSelectChange = action((e: React.ChangeEvent<HTMLSelectElement>) => {
-        this._docTypeString = e.target.value;
-        this.submitSearch();
-    });
-
-    onResultClick = action((doc: Doc) => {
-        this.selectElement(doc);
-        this._selectedResult = doc;
-    });
-
-    static foreachRecursiveDoc(docs: Doc[], func: (doc: Doc) => void) {
-        const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
-        let newarray: Doc[] = [];
-        while (docs.length > 0) {
-            newarray = [];
-            docs.filter(d => d).forEach(d => {
-                const dtype = StrCast(d.type, "string") as DocumentType;
-                if (dtype && !blockedTypes.includes(dtype)) {
-                    const fieldKey = Doc.LayoutFieldKey(d);
-                    const annos = !Field.toString(Doc.LayoutField(d) as Field).includes("CollectionView");
-                    const data = d[annos ? fieldKey + "-annotations" : fieldKey];
-                    data && newarray.push(...DocListCast(data));
-                    func(d);
-                }
-            });
-            docs = newarray;
-        }
-    }
-
-    @action
-    searchCollection(query: string) {
-        const selectedCollection = CollectionDockingView.Instance;
-        query = query.toLowerCase();
-
-        if (selectedCollection !== undefined) {
-            console.log("hello111")
-            // this._currentSelectedCollection = selectedCollection;
-            const docs = DocListCast(selectedCollection.dataDoc[Doc.LayoutFieldKey(selectedCollection.dataDoc)]);
-            const found: [Doc, string[], string[]][] = [];
-            SearchBox.foreachRecursiveDoc(docs, (doc: Doc) => {
-                console.log("HELLO")
-                if (this._docTypeString == "all" || this._docTypeString == doc.type) {
-                    const hlights = new Set<string>();
-                    SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
-                    Array.from(hlights.keys()).length > 0 && found.push([doc, Array.from(hlights.keys()), []]);
-                }
-            });
-
-            this._results = found;
-            //this.setSearchFilter(selectedCollection, this.filter && found.length ? this._docsforfilter : undefined);
-        }
-    }
-
-    static documentKeys(doc: Doc) {
-        const keys: { [key: string]: boolean } = {};
-        // bcz: ugh.  this is untracked since otherwise a large collection of documents will blast the server for all their fields.
-        //  then as each document's fields come back, we update the documents _proxies.  Each time we do this, the whole schema will be
-        //  invalidated and re-rendered.   This workaround will inquire all of the document fields before the options button is clicked.
-        //  then by the time the options button is clicked, all of the fields should be in place.  If a new field is added while this menu
-        //  is displayed (unlikely) it won't show up until something else changes.
-        //TODO Types
-        Doc.GetAllPrototypes(doc).map(proto => Object.keys(proto).forEach(key => keys[key] = false));
-        return Array.from(Object.keys(keys));
-    }
-
-    @action
-    submitSearch = async () => {
-        Doc.ClearSearchMatches();
-        this._results = [];
-
-        this.dataDoc[this.fieldKey] = new List<Doc>([]);
-        let query = StrCast(this._searchString);
-        Doc.SetSearchQuery(query);
-        this._results = [];
-
-        if (query) {
-            this.searchCollection(query);
-        }
-    }
-
-    selectElement = async (doc: Doc) => {
-        await DocumentManager.Instance.jumpToDocument(doc, true); // documents open in new tab instead of on right
-    }
-
-    render() {
-        const results = this._results.map(result => {
-            var className = "searchBox-results-scroll-view-result";
-
-            if (this._selectedResult == result[0]) {
-                className += " searchBox-results-scroll-view-result-selected"
-            }
-
-            return (<div key={result[0][Id]} onClick={() => this.onResultClick(result[0])} className={className}><div className="titletitle">{result[0].title}</div></div>)
-        })
-
-        return (
-            <div style={{ pointerEvents: "all" }} className="searchBox-container">
-                <div className="searchBox-bar">
-                    <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
-                        <option value="all">All</option>
-                        <option value="rtf">Text</option>
-                        <option value="img">Img</option>
-                        <option value="pdf">PDF</option>
-                        <option value="video">Vid</option>
-                        <option value="audio">Aud</option>
-                        <option value="inks">Ink</option>
-                        <option value="col">Col</option>
-                    </select>
-                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" />
-                </div >
-                <div className="searchBox-results-container">
-                    <div className="searchBox-results-count">
-                        {`${this._results.length}` + " result" + (this._results.length == 1 ? "" : "s")}
-                    </div>
-                    <div className="searchBox-results-scroll-view">
-                        {results}
-                    </div>
-                </div>
-            </div >
-        );
-    }
-}*/
\ No newline at end of file
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From e7bbdd3b489fea1c508af53345cd0d1f31685cb9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 6 Aug 2021 18:03:38 -0400
Subject: collabortion fixes: added new acl for allowing people to edit their
 own text within the same note, fixed playground fields to write to the server
 without updating other clients.

---
 src/client/DocServer.ts                            |  5 +-
 src/client/documents/Documents.ts                  | 10 ++--
 src/client/util/CurrentUserUtils.ts                |  6 +-
 src/client/util/SharingManager.tsx                 | 13 ++--
 src/client/views/DocComponent.tsx                  |  6 +-
 src/client/views/MainView.tsx                      |  2 +-
 src/client/views/MarqueeAnnotator.tsx              |  4 +-
 src/client/views/PropertiesView.tsx                | 14 ++---
 .../collections/collectionFreeForm/MarqueeView.tsx |  4 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx | 12 +++-
 .../formattedText/ProsemirrorExampleTransfer.ts    | 70 ++++++++++++++--------
 src/fields/Doc.ts                                  |  6 +-
 src/fields/util.ts                                 | 22 ++++---
 13 files changed, 105 insertions(+), 69 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 59278d2af..d9ae7d64c 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -59,7 +59,10 @@ export namespace DocServer {
     export var PlaygroundFields: string[];
     export function setPlaygroundFields(livePlaygroundFields: string[]) {
         DocServer.PlaygroundFields = livePlaygroundFields;
-        livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.Playground));
+        livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.LivePlayground));
+    }
+    export function IsPlaygroundField(field: string) {
+        return DocServer.PlaygroundFields?.includes(field.replace(/^_/, ""));
     }
 
     export function setFieldWriteMode(field: string, writeMode: WriteMode) {
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 24f777e88..93f0880a4 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -577,7 +577,7 @@ export namespace Docs {
             dataProps.creationDate = new DateField;
             dataProps[`${fieldKey}-lastModified`] = new DateField;
             dataProps["acl-Override"] = "None";
-            dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
+            dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
 
             dataProps[fieldKey] = data;
 
@@ -588,7 +588,7 @@ export namespace Docs {
 
             viewProps.author = Doc.CurrentUserEmail;
             viewProps["acl-Override"] = "None";
-            viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
+            viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
             const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true);
             ![DocumentType.LINK, DocumentType.MARKER, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc);
 
@@ -699,7 +699,7 @@ export namespace Docs {
             I.author = Doc.CurrentUserEmail;
             I.rotation = 0;
             I.data = new InkField(points);
-            I["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
+            I["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
             I["acl-Override"] = "None";
             I[Initializing] = false;
             return I;
@@ -1038,8 +1038,8 @@ export namespace DocUtils {
             title: ComputedField.MakeFunction("generateLinkTitle(self)") as any,
             "anchor1-useLinkSmallAnchor": source.doc.useLinkSmallAnchor ? true : undefined,
             "anchor2-useLinkSmallAnchor": target.doc.useLinkSmallAnchor ? true : undefined,
-            "acl-Public": SharingPermissions.Add,
-            "_acl-Public": SharingPermissions.Add,
+            "acl-Public": SharingPermissions.Augment,
+            "_acl-Public": SharingPermissions.Augment,
             layout_linkView: Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null),
             linkDisplay: true, hidden: true,
             linkRelationship,
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 1af6607a7..14c43fb1c 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -917,7 +917,7 @@ export class CurrentUserUtils {
                 linkDocs = new Doc(linkDatabaseId, true);
                 (linkDocs as Doc).author = Doc.CurrentUserEmail;
                 (linkDocs as Doc).data = new List<Doc>([]);
-                (linkDocs as Doc)["acl-Public"] = SharingPermissions.Add;
+                (linkDocs as Doc)["acl-Public"] = SharingPermissions.Augment;
             }
             doc.myLinkDatabase = new PrefetchProxy(linkDocs);
         }
@@ -926,10 +926,10 @@ export class CurrentUserUtils {
             if (!sharedDocs) {
                 sharedDocs = Docs.Create.TreeDocument([], {
                     title: "My SharedDocs", childDropAction: "alias", system: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 50, _gridGap: 15,
-                    _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Add, "_acl-Public": SharingPermissions.Add,
+                    _showTitle: "title", ignoreClick: true, _lockedPosition: true, "acl-Public": SharingPermissions.Augment, "_acl-Public": SharingPermissions.Augment,
                     _chromeHidden: true, boxShadow: "0 0",
                 }, sharingDocumentId + "outer", sharingDocumentId);
-                (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Add;
+                (sharedDocs as Doc)["acl-Public"] = (sharedDocs as Doc)[DataSym]["acl-Public"] = SharingPermissions.Augment;
             }
             if (sharedDocs instanceof Doc) {
                 Doc.GetProto(sharedDocs).userColor = sharedDocs.userColor || "rgb(202, 202, 202)";
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index d283510b7..a8972b988 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
 import * as React from "react";
 import Select from "react-select";
 import * as RequestPromise from "request-promise";
-import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
+import { AclAugment, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, Opt, AclSelfEdit } from "../../fields/Doc";
 import { List } from "../../fields/List";
 import { Cast, NumCast, StrCast } from "../../fields/Types";
 import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from "../../fields/util";
@@ -85,7 +85,8 @@ export class SharingManager extends React.Component<{}> {
     private AclMap = new Map<symbol, string>([
         [AclPrivate, SharingPermissions.None],
         [AclReadonly, SharingPermissions.View],
-        [AclAddonly, SharingPermissions.Add],
+        [AclAugment, SharingPermissions.Augment],
+        [AclSelfEdit, SharingPermissions.SelfEdit],
         [AclEdit, SharingPermissions.Edit],
         [AclAdmin, SharingPermissions.Admin]
     ]);
@@ -101,7 +102,7 @@ export class SharingManager extends React.Component<{}> {
             this.targetDoc = target_doc || target?.props.Document;
             DictationOverlay.Instance.hasActiveModal = true;
             this.isOpen = this.targetDoc !== undefined;
-            this.permissions = SharingPermissions.Add;
+            this.permissions = SharingPermissions.Augment;
         });
     }
 
@@ -366,10 +367,10 @@ export class SharingManager extends React.Component<{}> {
         const dropdownValues: string[] = Object.values(SharingPermissions);
         if (!uniform) dropdownValues.unshift("-multiple-");
         if (override) dropdownValues.unshift("None");
-        return dropdownValues.filter(permission => permission !== SharingPermissions.View).map(permission =>
+        return dropdownValues.filter(permission => !Doc.UserDoc().noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)).map(permission =>
             (
                 <option key={permission} value={permission}>
-                    {permission === SharingPermissions.Add ? "Can Augment" : permission}
+                    {permission}
                 </option>
             )
         );
@@ -546,7 +547,7 @@ export class SharingManager extends React.Component<{}> {
                             </select>
                         ) : (
                                 <div className={"permissions-dropdown"}>
-                                    {permissions === SharingPermissions.Add ? "Can Augment" : permissions}
+                                    {permissions}
                                 </div>
                             )}
                     </div>
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index fc36c7e43..99c695a4a 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,4 +1,4 @@
-import { Doc, Opt, DataSym, AclReadonly, AclAddonly, AclPrivate, AclEdit, AclSym, DocListCastAsync, DocListCast, AclAdmin } from '../../fields/Doc';
+import { Doc, Opt, DataSym, AclReadonly, AclAugment, AclPrivate, AclEdit, AclSym, DocListCast, AclAdmin, AclSelfEdit } from '../../fields/Doc';
 import { Touchable } from './Touchable';
 import { computed, action, observable } from 'mobx';
 import { Cast, BoolCast, ScriptCast } from '../../fields/Types';
@@ -131,7 +131,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
         removeDocument(doc: Doc | Doc[], annotationKey?: string, leavePushpin?: boolean): boolean {
             const effectiveAcl = GetEffectiveAcl(this.dataDoc);
             const indocs = doc instanceof Doc ? [doc] : doc;
-            const docs = indocs.filter(doc => effectiveAcl === AclEdit || effectiveAcl === AclAdmin || GetEffectiveAcl(doc) === AclAdmin);
+            const docs = indocs.filter(doc => [AclEdit, AclAdmin].includes(effectiveAcl) || GetEffectiveAcl(doc) === AclAdmin);
             if (docs.length) {
                 setTimeout(() => docs.map(doc => { // this allows 'addDocument' to see the annotationOn field in order to create a pushin
                     Doc.SetInPlace(doc, "isPushpin", undefined, true);
@@ -199,7 +199,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
                         });
                     }
 
-                    if (effectiveAcl === AclAddonly) {
+                    if (effectiveAcl === AclAugment) {
                         added.map(doc => {
                             if ([AclAdmin, AclEdit].includes(GetEffectiveAcl(doc))) inheritParentAcls(CurrentUserUtils.ActiveDashboard, doc);
                             doc.context = this.props.Document;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 005e46836..8f37172a0 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -107,7 +107,7 @@ export class MainView extends React.Component {
         new InkStrokeProperties();
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
-            DocServer.setPlaygroundFields(["x", "y", "dataTransition", "_autoHeight", "_showSidebar", "showSidebar", "_sidebarWidthPercent", "_width", "_height", "width", "height", "_viewTransition", "_panX", "_panY", "_viewScale", "_scrollTop", "hidden", "_curPage", "_viewType", "_chromeHidden", "nativeWidth", "_nativeWidth"]); // can play with these fields on someone else's
+            DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition", "panX", "panY", "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
 
diff --git a/src/client/views/MarqueeAnnotator.tsx b/src/client/views/MarqueeAnnotator.tsx
index 805cda95c..a3a3bce56 100644
--- a/src/client/views/MarqueeAnnotator.tsx
+++ b/src/client/views/MarqueeAnnotator.tsx
@@ -1,6 +1,6 @@
 import { action, observable, ObservableMap, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { AclAddonly, AclAdmin, AclEdit, DataSym, Doc, Opt } from "../../fields/Doc";
+import { AclAugment, AclAdmin, AclEdit, DataSym, Doc, Opt, AclSelfEdit } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
 import { List } from "../../fields/List";
 import { NumCast } from "../../fields/Types";
@@ -156,7 +156,7 @@ export class MarqueeAnnotator extends React.Component<MarqueeAnnotatorProps> {
     highlight = (color: string, isLinkButton: boolean, savedAnnotations?: ObservableMap<number, HTMLDivElement[]>) => {
         // creates annotation documents for current highlights
         const effectiveAcl = GetEffectiveAcl(this.props.rootDoc[DataSym]);
-        const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations);
+        const annotationDoc = [AclAugment, AclSelfEdit, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color, isLinkButton, savedAnnotations);
         !savedAnnotations && annotationDoc && this.props.addDocument(annotationDoc);
         return annotationDoc as Doc ?? undefined;
     }
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 8136edf04..de437e1df 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -5,7 +5,7 @@ import { intersection } from "lodash";
 import { action, autorun, computed, Lambda, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { ColorState, SketchPicker } from "react-color";
-import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, Opt, WidthSym } from "../../fields/Doc";
+import { AclAugment, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, Field, HeightSym, Opt, WidthSym, AclSelfEdit } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
 import { InkField } from "../../fields/InkField";
 import { ComputedField } from "../../fields/ScriptField";
@@ -342,12 +342,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         return <select className="permissions-select"
             value={permission}
             onChange={e => this.changePermissions(e, user)}>
-            {dropdownValues.filter(permission => permission !== SharingPermissions.View).map(permission => {
-                return (
-                    <option key={permission} value={permission}>
-                        {permission === SharingPermissions.Add ? "Can Augment" : permission}
-                    </option>);
-            })}
+            {dropdownValues.filter(permission =>
+                !Doc.UserDoc().noviceMode || ![SharingPermissions.View, SharingPermissions.SelfEdit].includes(permission as any)).map(permission =>
+                    <option key={permission} value={permission}>  {permission}  </option>)}
         </select>;
     }
 
@@ -402,7 +399,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             [AclUnset, "None"],
             [AclPrivate, SharingPermissions.None],
             [AclReadonly, SharingPermissions.View],
-            [AclAddonly, SharingPermissions.Add],
+            [AclAugment, SharingPermissions.Augment],
+            [AclSelfEdit, SharingPermissions.SelfEdit],
             [AclEdit, SharingPermissions.Edit],
             [AclAdmin, SharingPermissions.Admin]
         ]);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 846d28214..19da7ea00 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,6 +1,6 @@
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { AclAddonly, AclAdmin, AclEdit, DataSym, Doc, Opt } from "../../../../fields/Doc";
+import { AclAugment, AclAdmin, AclEdit, DataSym, Doc, Opt } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
 import { InkData, InkField, InkTool } from "../../../../fields/InkField";
 import { List } from "../../../../fields/List";
@@ -298,7 +298,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             this._downX = x;
             this._downY = y;
             const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
-            if ([AclAdmin, AclEdit, AclAddonly].includes(effectiveAcl)) {
+            if ([AclAdmin, AclEdit, AclAugment].includes(effectiveAcl)) {
                 PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument, this.props.nudge);
             }
             this.clearSelection();
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index edd7177de..f7bed2fa1 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -11,7 +11,7 @@ import { ReplaceStep } from 'prosemirror-transform';
 import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { DateField } from '../../../../fields/DateField';
-import { AclAdmin, AclEdit, DataSym, Doc, DocListCast, DocListCastAsync, Field, ForceServerWrite, HeightSym, Opt, UpdatingFromServer, WidthSym } from "../../../../fields/Doc";
+import { AclAdmin, AclEdit, AclSelfEdit, DataSym, Doc, DocListCast, DocListCastAsync, Field, ForceServerWrite, HeightSym, Opt, UpdatingFromServer, WidthSym, AclAugment } from "../../../../fields/Doc";
 import { documentSchema } from '../../../../fields/documentSchemas';
 import { Id } from '../../../../fields/FieldSymbols';
 import { InkTool } from '../../../../fields/InkField';
@@ -253,7 +253,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             const removeSelection = (json: string | undefined) => json?.indexOf("\"storedMarks\"") === -1 ?
                 json?.replace(/"selection":.*/, "") : json?.replace(/"selection":"\"storedMarks\""/, "\"storedMarks\"");
 
-            if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) {
+            if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin || effectiveAcl === AclSelfEdit) {
                 const accumTags = [] as string[];
                 state.tr.doc.nodesBetween(0, state.doc.content.size, (node: any, pos: number, parent: any) => {
                     if (node.type === schema.nodes.dashField && node.attrs.fieldKey.startsWith("#")) {
@@ -1401,6 +1401,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             this._rules!.EnteringStyle = false;
         }
         e.stopPropagation();
+        for (var i = state.selection.from; i < state.selection.to; i++) {
+            const node = state.doc.resolve(i);
+            if (node?.marks?.().some(mark => mark.type === schema.marks.user_mark &&
+                mark.attrs.userid !== Doc.CurrentUserEmail) &&
+                [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.rootDoc))) {
+                e.preventDefault();
+            }
+        }
         switch (e.key) {
             case "Escape":
                 this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from)));
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index d5c77786c..1f78b2204 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -7,13 +7,14 @@ import { splitListItem, wrapInList, } from "prosemirror-schema-list";
 import { EditorState, Transaction, TextSelection } from "prosemirror-state";
 import { SelectionManager } from "../../../util/SelectionManager";
 import { NumCast, BoolCast, Cast, StrCast } from "../../../../fields/Types";
-import { Doc, DataSym, DocListCast } from "../../../../fields/Doc";
+import { Doc, DataSym, DocListCast, AclAugment } from "../../../../fields/Doc";
 import { FormattedTextBox } from "./FormattedTextBox";
 import { Id } from "../../../../fields/FieldSymbols";
 import { Docs } from "../../../documents/Documents";
 import { Utils } from "../../../../Utils";
 import { listSpec } from "../../../../fields/Schema";
 import { List } from "../../../../fields/List";
+import { GetEffectiveAcl } from "../../../../fields/util";
 
 const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
 
@@ -70,25 +71,39 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
         return false;
     };
 
+    const canEdit = (state: any) => {
+        for (var i = state.selection.from; i < state.selection.to; i++) {
+            const node = state.doc.resolve(i);
+            if (node?.marks?.().some((mark: any) => mark.type === schema.marks.user_mark &&
+                mark.attrs.userid !== Doc.CurrentUserEmail) &&
+                GetEffectiveAcl(props.Document) === AclAugment) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    const toggleEditableMark = (mark: any) => (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && toggleMark(mark)(state, dispatch);
+
     //History commands
     bind("Mod-z", undo);
     bind("Shift-Mod-z", redo);
     !mac && bind("Mod-y", redo);
 
     //Commands to modify Mark
-    bind("Mod-b", toggleMark(schema.marks.strong));
-    bind("Mod-B", toggleMark(schema.marks.strong));
+    bind("Mod-b", toggleEditableMark(schema.marks.strong));
+    bind("Mod-B", toggleEditableMark(schema.marks.strong));
 
-    bind("Mod-e", toggleMark(schema.marks.em));
-    bind("Mod-E", toggleMark(schema.marks.em));
+    bind("Mod-e", toggleEditableMark(schema.marks.em));
+    bind("Mod-E", toggleEditableMark(schema.marks.em));
 
-    bind("Mod-*", toggleMark(schema.marks.code));
+    bind("Mod-*", toggleEditableMark(schema.marks.code));
 
-    bind("Mod-u", toggleMark(schema.marks.underline));
-    bind("Mod-U", toggleMark(schema.marks.underline));
+    bind("Mod-u", toggleEditableMark(schema.marks.underline));
+    bind("Mod-U", toggleEditableMark(schema.marks.underline));
 
     //Commands for lists
-    bind("Ctrl-i", wrapInList(schema.nodes.ordered_list));
+    bind("Ctrl-i", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && wrapInList(schema.nodes.ordered_list)(state, dispatch as any));
 
     bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
         /// bcz; Argh!!  replace layotuTEmpalteString with a onTab prop conditionally handles Tab);
@@ -96,6 +111,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
             if (!props.LayoutTemplateString) return addTextBox(false, true);
             return true;
         }
+        if (!canEdit(state)) return true;
         const ref = state.selection;
         const range = ref.$from.blockRange(ref.$to);
         const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
@@ -121,6 +137,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
         /// bcz; Argh!!  replace with a onShiftTab prop conditionally handles Tab);
         if (props.Document._singleLine) return true;
+        if (!canEdit(state)) return true;
         const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
 
         if (!liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => {
@@ -140,24 +157,19 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     });
 
     //Commands to modify BlockType
-    bind("Ctrl->", wrapIn(schema.nodes.blockquote));
-    bind("Alt-\\", setBlockType(schema.nodes.paragraph));
-    bind("Shift-Ctrl-\\", setBlockType(schema.nodes.code_block));
+    bind("Ctrl->", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit((state) && wrapIn(schema.nodes.blockquote)(state, dispatch as any)));
+    bind("Alt-\\", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && setBlockType(schema.nodes.paragraph)(state, dispatch as any));
+    bind("Shift-Ctrl-\\", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && setBlockType(schema.nodes.code_block)(state, dispatch as any));
 
-    bind("Ctrl-m", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: "math" + Utils.GenerateGuid() })));
-    });
+    bind("Ctrl-m", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(schema.nodes.equation.create({ fieldKey: "math" + Utils.GenerateGuid() }))));
 
     for (let i = 1; i <= 6; i++) {
-        bind("Shift-Ctrl-" + i, setBlockType(schema.nodes.heading, { level: i }));
+        bind("Shift-Ctrl-" + i, (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && setBlockType(schema.nodes.heading, { level: i })(state, dispatch as any));
     }
 
     //Command to create a horizontal break line
     const hr = schema.nodes.horizontal_rule;
-    bind("Mod-_", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView());
-        return true;
-    });
+    bind("Mod-_", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && dispatch(state.tr.replaceSelectionWith(hr.create()).scrollIntoView()));
 
     //Command to unselect all
     bind("Escape", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
@@ -173,13 +185,15 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     };
 
     //Command to create a text document to the right of the selected textbox
-    bind("Alt-Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => addTextBox(false, true));
+    bind("Alt-Enter", () => addTextBox(false, true));
 
     //Command to create a text document to the bottom of the selected textbox
-    bind("Ctrl-Enter", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => addTextBox(true, true));
+    bind("Ctrl-Enter", () => addTextBox(true, true));
 
     // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
     bind("Backspace", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
+        if (!canEdit(state)) return true;
+
         if (!deleteSelection(state, (tx: Transaction<Schema<any, any>>) => {
             dispatch(updateBullets(tx, schema));
         })) {
@@ -200,6 +214,9 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
     //command to break line
     bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
         if (addTextBox(true, false)) return true;
+
+        if (!canEdit(state)) return true;
+
         const trange = state.selection.$from.blockRange(state.selection.$to);
         const path = (state.selection.$from as any).path;
         const depth = trange ? liftTarget(trange) : undefined;
@@ -238,18 +255,19 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey
 
     //Command to create a blank space
     bind("Space", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+        if (!canEdit(state)) return true;
         const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
         dispatch(splitMetadata(marks, state.tr));
         return false;
     });
 
-    bind("Alt-ArrowUp", joinUp);
-    bind("Alt-ArrowDown", joinDown);
-    bind("Mod-BracketLeft", lift);
+    bind("Alt-ArrowUp", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && joinUp(state, dispatch as any));
+    bind("Alt-ArrowDown", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && joinDown(state, dispatch as any));
+    bind("Mod-BracketLeft", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => canEdit(state) && lift(state, dispatch as any));
 
     const cmd = chainCommands(exitCode, (state, dispatch) => {
         if (dispatch) {
-            dispatch(state.tr.replaceSelectionWith(schema.nodes.hard_break.create()).scrollIntoView());
+            canEdit(state) && dispatch(state.tr.replaceSelectionWith(schema.nodes.hard_break.create()).scrollIntoView());
             return true;
         }
         return false;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 0cbfaf067..85ea3cfa9 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -90,7 +90,8 @@ export const DirectLinksSym = Symbol("DirectLinks");
 export const AclUnset = Symbol("AclUnset");
 export const AclPrivate = Symbol("AclOwnerOnly");
 export const AclReadonly = Symbol("AclReadOnly");
-export const AclAddonly = Symbol("AclAddonly");
+export const AclAugment = Symbol("AclAugment");
+export const AclSelfEdit = Symbol("AclSelfEdit");
 export const AclEdit = Symbol("AclEdit");
 export const AclAdmin = Symbol("AclAdmin");
 export const UpdatingFromServer = Symbol("UpdatingFromServer");
@@ -102,7 +103,8 @@ const AclMap = new Map<string, symbol>([
     ["None", AclUnset],
     [SharingPermissions.None, AclPrivate],
     [SharingPermissions.View, AclReadonly],
-    [SharingPermissions.Add, AclAddonly],
+    [SharingPermissions.Augment, AclAugment],
+    [SharingPermissions.SelfEdit, AclSelfEdit],
     [SharingPermissions.Edit, AclEdit],
     [SharingPermissions.Admin, AclAdmin]
 ]);
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 526e5af72..2bb6b45c2 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,5 +1,5 @@
 import { UndoManager } from "../client/util/UndoManager";
-import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, DataSym, DocListCast, AclAdmin, HeightSym, WidthSym, updateCachedAcls, AclUnset, DocListCastAsync, ForceServerWrite, Initializing } from "./Doc";
+import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAugment, AclSym, DataSym, DocListCast, AclAdmin, HeightSym, WidthSym, updateCachedAcls, AclUnset, DocListCastAsync, ForceServerWrite, Initializing, AclSelfEdit } from "./Doc";
 import { SerializationHelper } from "../client/util/SerializationHelper";
 import { ProxyField, PrefetchProxy } from "./Proxy";
 import { RefField } from "./RefField";
@@ -14,6 +14,7 @@ import CursorField from "./CursorField";
 import { List } from "./List";
 import { SnappingManager } from "../client/util/SnappingManager";
 import { computedFn } from "mobx-utils";
+import { RichTextField } from "./RichTextField";
 
 function _readOnlySetter(): never {
     throw new Error("Documents can't be modified in read-only mode");
@@ -77,7 +78,9 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
     const fromServer = target[UpdatingFromServer];
     const sameAuthor = fromServer || (receiver.author === Doc.CurrentUserEmail);
     const writeToDoc = sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || (writeMode !== DocServer.WriteMode.LiveReadonly);
-    const writeToServer = (sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || writeMode === DocServer.WriteMode.Default) && !DocServer.Control.isReadOnly();// && !playgroundMode;
+    const writeToServer =
+        (sameAuthor || effectiveAcl === AclEdit || effectiveAcl === AclAdmin || (effectiveAcl === AclSelfEdit && (value instanceof RichTextField))) &&
+        !DocServer.Control.isReadOnly();
 
     if (writeToDoc) {
         if (value === undefined) {
@@ -157,9 +160,10 @@ export function inheritParentAcls(parent: Doc, child: Doc) {
  */
 export enum SharingPermissions {
     Admin = "Admin",
-    Edit = "Can Edit",
-    Add = "Can Augment",
-    View = "Can View",
+    Edit = "Edit",
+    SelfEdit = "Self Edit",
+    Augment = "Augment",
+    View = "View",
     None = "Not Shared"
 }
 
@@ -176,7 +180,7 @@ export function GetEffectiveAcl(target: any, user?: string): symbol {
 
 function getPropAcl(target: any, prop: string | symbol | number) {
     if (prop === UpdatingFromServer || prop === Initializing || target[UpdatingFromServer] || prop === AclSym) return AclAdmin;  // requesting the UpdatingFromServer prop or AclSym must always go through to keep the local DB consistent
-    if (prop && DocServer.PlaygroundFields?.includes(prop.toString())) return AclEdit; // playground props are always editable
+    if (prop && DocServer.IsPlaygroundField(prop.toString())) return AclEdit; // playground props are always editable
     return GetEffectiveAcl(target);
 }
 
@@ -192,7 +196,8 @@ function getEffectiveAcl(target: any, user?: string): symbol {
         HierarchyMapping = HierarchyMapping || new Map<symbol, number>([
             [AclPrivate, 0],
             [AclReadonly, 1],
-            [AclAddonly, 2],
+            [AclAugment, 2],
+            [AclSelfEdit, 2.5],
             [AclEdit, 3],
             [AclAdmin, 4]
         ]);
@@ -235,6 +240,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
         ["Not Shared", 0],
         ["Can View", 1],
         ["Can Augment", 2],
+        ["Self Edit", 2.5],
         ["Can Edit", 3],
         ["Admin", 4]
     ]);
@@ -294,7 +300,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
 export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
     let prop = in_prop;
     const effectiveAcl = getPropAcl(target, prop);
-    if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true;
+    if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin && !(effectiveAcl === AclSelfEdit && value instanceof RichTextField)) return true;
     // if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't
     if (typeof prop === "string" && prop.startsWith("acl") && (effectiveAcl !== AclAdmin || ![...Object.values(SharingPermissions), undefined, "None"].includes(value))) return true;
     // if (typeof prop === "string" && prop.startsWith("acl") && !["Can Edit", "Can Augment", "Can View", "Not Shared", undefined].includes(value)) return true;
-- 
cgit v1.2.3-70-g09d2


From 8480bcbe9e5ddea4bac64273c2e6581d36bb49de Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 6 Aug 2021 18:25:55 -0400
Subject: switched back to Playground fields and included
 width/height/natiive(w,h) to playgorund list

---
 src/client/DocServer.ts       | 2 +-
 src/client/views/MainView.tsx | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index d9ae7d64c..5712a1d64 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -59,7 +59,7 @@ export namespace DocServer {
     export var PlaygroundFields: string[];
     export function setPlaygroundFields(livePlaygroundFields: string[]) {
         DocServer.PlaygroundFields = livePlaygroundFields;
-        livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.LivePlayground));
+        livePlaygroundFields.forEach(f => DocServer.setFieldWriteMode(f, DocServer.WriteMode.Playground));
     }
     export function IsPlaygroundField(field: string) {
         return DocServer.PlaygroundFields?.includes(field.replace(/^_/, ""));
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 8f37172a0..2be3c3135 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -107,7 +107,9 @@ export class MainView extends React.Component {
         new InkStrokeProperties();
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
-            DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition", "panX", "panY", "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
+            DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
+                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight",
+                "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
 
-- 
cgit v1.2.3-70-g09d2


From 81ae5175aebf7e14a781a73d4a7cbaec0b8f3e4a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 9 Aug 2021 14:26:14 -0400
Subject: fixed augment only text to resize correctly with autoheight. fixed
 acls to cache correctly for new documents. fixed links to be shared across
 users.  fixed links to always default to public.

---
 src/client/DocServer.ts                            |  2 +-
 src/client/documents/Documents.ts                  |  8 ++-
 src/client/util/CurrentUserUtils.ts                | 16 +++---
 src/client/util/LinkManager.ts                     | 67 ++++++++++++++--------
 src/client/util/SettingsManager.tsx                |  3 +-
 src/client/util/SharingManager.tsx                 |  4 +-
 src/client/views/MainView.tsx                      |  2 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx | 20 ++++---
 src/fields/util.ts                                 |  4 +-
 9 files changed, 79 insertions(+), 47 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 5712a1d64..f4e3a22cf 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,6 +1,6 @@
 import * as io from 'socket.io-client';
 import { MessageStore, YoutubeQueryTypes, GestureContent, MobileInkOverlayContent, UpdateMobileInkOverlayPositionContent, MobileDocumentUploadContent } from "./../server/Message";
-import { Opt, Doc, UpdatingFromServer } from '../fields/Doc';
+import { Opt, Doc, UpdatingFromServer, updateCachedAcls } from '../fields/Doc';
 import { Utils, emptyFunction } from '../Utils';
 import { SerializationHelper } from './util/SerializationHelper';
 import { RefField } from '../fields/RefField';
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 93f0880a4..48886aa3b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1,7 +1,7 @@
 import { action, runInAction } from "mobx";
 import { basename, extname } from "path";
 import { DateField } from "../../fields/DateField";
-import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, Initializing } from "../../fields/Doc";
+import { Doc, DocListCast, DocListCastAsync, Field, HeightSym, Opt, WidthSym, Initializing, updateCachedAcls } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
 import { HtmlField } from "../../fields/HtmlField";
 import { InkField } from "../../fields/InkField";
@@ -577,7 +577,7 @@ export namespace Docs {
             dataProps.creationDate = new DateField;
             dataProps[`${fieldKey}-lastModified`] = new DateField;
             dataProps["acl-Override"] = "None";
-            dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
+            dataProps["acl-Public"] = options["acl-Public"] ? options["acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
 
             dataProps[fieldKey] = data;
 
@@ -588,13 +588,15 @@ export namespace Docs {
 
             viewProps.author = Doc.CurrentUserEmail;
             viewProps["acl-Override"] = "None";
-            viewProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
+            viewProps["acl-Public"] = options["_acl-Public"] ? options["_acl-Public"] : Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Augment;
             const viewDoc = Doc.assign(Doc.MakeDelegate(dataDoc, delegId), viewProps, true, true);
             ![DocumentType.LINK, DocumentType.MARKER, DocumentType.LABEL].includes(viewDoc.type as any) && DocUtils.MakeLinkToActiveAudio(() => viewDoc);
 
             !Doc.IsSystem(dataDoc) && ![DocumentType.MARKER, DocumentType.KVP, DocumentType.LINK, DocumentType.LINKANCHOR].includes(proto.type as any) &&
                 !dataDoc.isFolder && !dataProps.annotationOn && Doc.AddDocToList(Cast(Doc.UserDoc().myFileOrphans, Doc, null), "data", dataDoc);
 
+            updateCachedAcls(dataDoc);
+            updateCachedAcls(viewDoc);
             return viewDoc;
         }
 
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 14c43fb1c..34990e121 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -2,13 +2,14 @@ import { computed, observable, reaction } from "mobx";
 import * as rp from 'request-promise';
 import { DataSym, Doc, DocListCast, DocListCastAsync } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
+import { InkTool } from "../../fields/InkField";
 import { List } from "../../fields/List";
 import { PrefetchProxy } from "../../fields/Proxy";
 import { RichTextField } from "../../fields/RichTextField";
 import { listSpec } from "../../fields/Schema";
 import { SchemaHeaderField } from "../../fields/SchemaHeaderField";
 import { ComputedField, ScriptField } from "../../fields/ScriptField";
-import { BoolCast, Cast, NumCast, PromiseValue, StrCast, DateCast } from "../../fields/Types";
+import { BoolCast, Cast, DateCast, NumCast, PromiseValue, StrCast } from "../../fields/Types";
 import { nullAudio } from "../../fields/URLField";
 import { SharingPermissions } from "../../fields/util";
 import { Utils } from "../../Utils";
@@ -19,6 +20,7 @@ import { Networking } from "../Network";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import { DimUnit } from "../views/collections/collectionMulticolumn/CollectionMulticolumnView";
 import { CollectionView, CollectionViewType } from "../views/collections/CollectionView";
+import { Colors } from "../views/global/globalEnums";
 import { MainView } from "../views/MainView";
 import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox";
 import { LabelBox } from "../views/nodes/LabelBox";
@@ -31,13 +33,10 @@ import { LinkManager } from "./LinkManager";
 import { Scripting } from "./Scripting";
 import { SearchUtil } from "./SearchUtil";
 import { SelectionManager } from "./SelectionManager";
-import { UndoManager } from "./UndoManager";
-import { SnappingManager } from "./SnappingManager";
-import { InkTool } from "../../fields/InkField";
-import { SharingManager } from "./SharingManager";
-import { computedFn } from "mobx-utils";
 import { ColorScheme } from "./SettingsManager";
-import { Colors } from "../views/global/globalEnums";
+import { SharingManager } from "./SharingManager";
+import { SnappingManager } from "./SnappingManager";
+import { UndoManager } from "./UndoManager";
 
 
 export let resolvedPorts: { server: number, socket: number };
@@ -915,6 +914,7 @@ export class CurrentUserUtils {
             let linkDocs = Docs.newAccount ? undefined : await DocServer.GetRefField(linkDatabaseId);
             if (!linkDocs) {
                 linkDocs = new Doc(linkDatabaseId, true);
+                (linkDocs as Doc).title = "LINK DATABASE: " + Doc.CurrentUserEmail;
                 (linkDocs as Doc).author = Doc.CurrentUserEmail;
                 (linkDocs as Doc).data = new List<Doc>([]);
                 (linkDocs as Doc)["acl-Public"] = SharingPermissions.Augment;
@@ -1029,7 +1029,7 @@ export class CurrentUserUtils {
         doc.fontFamily = StrCast(doc.fontFamily, "Arial");
         doc.fontColor = StrCast(doc.fontColor, "black");
         doc.fontHighlight = StrCast(doc.fontHighlight, "");
-        doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, true);
+        doc.defaultAclPrivate = BoolCast(doc.defaultAclPrivate, false);
         doc.activeCollectionBackground = StrCast(doc.activeCollectionBackground, "white");
         doc.activeCollectionNestedBackground = Cast(doc.activeCollectionNestedBackground, "string", null);
         doc.noviceMode = BoolCast(doc.noviceMode, true);
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index 8abfd740c..933b98a8c 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -1,4 +1,4 @@
-import { observable, observe, action } from "mobx";
+import { observable, observe, action, reaction, computed } from "mobx";
 import { computedFn } from "mobx-utils";
 import { DirectLinksSym, Doc, DocListCast, Field, Opt } from "../../fields/Doc";
 import { List } from "../../fields/List";
@@ -26,36 +26,41 @@ type CreateViewFunc = (doc: Doc, followLinkLocation: string, finished?: () => vo
 export class LinkManager {
 
     @observable static _instance: LinkManager;
-    @observable static userDocs: Doc[] = [];
+    @observable static userLinkDBs: Doc[] = [];
     public static currentLink: Opt<Doc>;
     public static get Instance() { return LinkManager._instance; }
+    public static addLinkDB = (linkDb: any) => LinkManager.userLinkDBs.push(linkDb);
+    static links: Doc[] = [];
     constructor() {
         LinkManager._instance = this;
         setTimeout(() => {
-            LinkManager.userDocs = [Doc.LinkDBDoc().data as Doc, ...SharingManager.Instance.users.map(user => user.linkDatabase)];
-            const addLinkToDoc = action((link: Doc): any => {
+            LinkManager.userLinkDBs = [];
+            const addLinkToDoc = (link: Doc) => {
                 const a1 = link?.anchor1;
                 const a2 = link?.anchor2;
-                if (a1 instanceof Promise || a2 instanceof Promise) return PromiseValue(a1).then(a1 => PromiseValue(a2).then(a2 => addLinkToDoc(link)));
-                if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
-                    Doc.GetProto(a1)[DirectLinksSym].add(link);
-                    Doc.GetProto(a2)[DirectLinksSym].add(link);
-                    Doc.GetProto(link)[DirectLinksSym].add(link);
-                }
-            });
-            const remLinkFromDoc = action((link: Doc): any => {
+                Promise.all([a1, a2]).then(action(() => {
+                    if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
+                        Doc.GetProto(a1)[DirectLinksSym].add(link);
+                        Doc.GetProto(a2)[DirectLinksSym].add(link);
+                        Doc.GetProto(link)[DirectLinksSym].add(link);
+                    }
+                }));
+            }
+            const remLinkFromDoc = (link: Doc) => {
                 const a1 = link?.anchor1;
                 const a2 = link?.anchor2;
-                if (a1 instanceof Promise || a2 instanceof Promise) return PromiseValue(a1).then(a1 => PromiseValue(a2).then(a2 => remLinkFromDoc(link)));
-                if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
-                    Doc.GetProto(a1)[DirectLinksSym].delete(link);
-                    Doc.GetProto(a2)[DirectLinksSym].delete(link);
-                    Doc.GetProto(link)[DirectLinksSym].delete(link);
-                }
-            });
-            const watchUserLinks = (userLinks: List<Doc>) => {
+                Promise.all([a1, a2]).then(action(() => {
+                    if (a1 instanceof Doc && a2 instanceof Doc && ((a1.author !== undefined && a2.author !== undefined) || link.author === Doc.CurrentUserEmail)) {
+                        Doc.GetProto(a1)[DirectLinksSym].delete(link);
+                        Doc.GetProto(a2)[DirectLinksSym].delete(link);
+                        Doc.GetProto(link)[DirectLinksSym].delete(link);
+                    }
+                }));
+            }
+            const watchUserLinkDB = (userLinkDBDoc: Doc) => {
+                LinkManager.links.push(...DocListCast(userLinkDBDoc.data));
                 const toRealField = (field: Field) => field instanceof ProxyField ? field.value() : field;  // see List.ts.  data structure is not a simple list of Docs, but a list of ProxyField/Fields
-                observe(userLinks, change => {
+                observe(userLinkDBDoc.data as Doc, change => {  // observe pushes/splices on a user link DB 'data' field (should only happen for local changes)
                     switch (change.type as any) {
                         case "splice":
                             (change as any).added.forEach((link: any) => addLinkToDoc(toRealField(link)));
@@ -64,13 +69,29 @@ export class LinkManager {
                         case "update": //let oldValue = change.oldValue;
                     }
                 }, true);
+                observe(userLinkDBDoc, "data",  // obsever when a new array of links is assigned as the link DB 'data' field (should happen whenever a remote user adds/removes a link)
+                    change => {
+                        switch (change.type as any) {
+                            case "update":
+                                Promise.all([...(change.oldValue as any as Doc[] || []), ...(change.newValue as any as Doc[] || [])]).then(doclist => {
+                                    const oldDocs = doclist.slice(0, (change.oldValue as any as Doc[] || []).length);
+                                    const newDocs = doclist.slice((change.oldValue as any as Doc[] || []).length, doclist.length);
+
+                                    const added = newDocs?.filter(link => !(oldDocs || []).includes(link));
+                                    const removed = oldDocs?.filter(link => !(newDocs || []).includes(link));
+                                    added?.forEach((link: any) => addLinkToDoc(toRealField(link)));
+                                    removed?.forEach((link: any) => remLinkFromDoc(toRealField(link)));
+                                });
+                        }
+                    }, true);
             };
-            observe(LinkManager.userDocs, change => {
+            observe(LinkManager.userLinkDBs, change => {
                 switch (change.type as any) {
-                    case "splice": (change as any).added.forEach(watchUserLinks); break;
+                    case "splice": (change as any).added.forEach(watchUserLinkDB); break;
                     case "update": //let oldValue = change.oldValue;
                 }
             }, true);
+            LinkManager.addLinkDB(Doc.LinkDBDoc());
         });
     }
 
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 3987497b8..bd91db779 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -268,7 +268,8 @@ export class SettingsManager extends React.Component<{}> {
                 <div className="tab-column-content">
                     <button onClick={() => GroupManager.Instance?.open()}>Manage groups</button>
                     <div className="default-acl">
-                        <input className="acl-check" type="checkbox" checked={BoolCast(Doc.UserDoc()?.defaultAclPrivate)} onChange={action(() => Doc.UserDoc().defaultAclPrivate = !Doc.UserDoc().defaultAclPrivate)} />
+                        <input className="acl-check" type="checkbox" checked={BoolCast(Doc.UserDoc()?.defaultAclPrivate)}
+                            onChange={action(() => Doc.UserDoc().defaultAclPrivate = !Doc.UserDoc().defaultAclPrivate)} />
                         <div className="acl-text">Default access private</div>
                     </div>
                 </div>
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index a8972b988..6c4556250 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -23,6 +23,7 @@ import { GroupManager, UserOptions } from "./GroupManager";
 import { GroupMemberView } from "./GroupMemberView";
 import { SelectionManager } from "./SelectionManager";
 import "./SharingManager.scss";
+import { LinkManager } from "./LinkManager";
 
 export interface User {
     email: string;
@@ -154,10 +155,11 @@ export class SharingManager extends React.Component<{}> {
                 }
             });
             return Promise.all(evaluating).then(() => {
-                runInAction(() => {
+                runInAction(async () => {
                     for (const sharer of sharingDocs) {
                         if (!this.users.find(user => user.user.email === sharer.user.email)) {
                             this.users.push(sharer);
+                            LinkManager.addLinkDB(sharer.linkDatabase);
                         }
                     }
                 });
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 2be3c3135..3d7446cbe 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -108,7 +108,7 @@ export class MainView extends React.Component {
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
             DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
-                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight",
+                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height",
                 "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index f7bed2fa1..9bba15b28 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -431,6 +431,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
         this.ProseRef = ele;
         this._dropDisposer?.();
         ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.layoutDoc));
+        // if (this.autoHeight) this.tryUpdateScrollHeight(); 
     }
 
     @undoBatch
@@ -1438,16 +1439,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
             }
         }
     }
-    tryUpdateScrollHeight() {
+    tryUpdateScrollHeight = () => {
         if (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath())) {
             const margins = 2 * NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0);
-            const proseHeight = !this.ProseRef ? 0 : Array.from(this.ProseRef.children[0].children).reduce((p, child) => p + Number(getComputedStyle(child).height.replace("px", "")), margins);
-            const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight);
-            if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {  // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
-                const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight;
-                if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) {
-                    setScrollHeight();
-                } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template.  So set a timeout and hope its arrived...
+            const children = this.ProseRef?.children.length ? Array.from(this.ProseRef.children[0].children) : undefined;
+            if (children) {
+                const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + Number(getComputedStyle(child).height.replace("px", "")), margins);
+                const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight);
+                if (scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {  // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
+                    const setScrollHeight = () => this.rootDoc[this.fieldKey + "-scrollHeight"] = scrollHeight;
+                    if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) {
+                        setScrollHeight();
+                    } else setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template.  So set a timeout and hope its arrived...
+                }
             }
         }
     }
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 2bb6b45c2..439c4d333 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -141,7 +141,9 @@ export function denormalizeEmail(email: string) {
 export function inheritParentAcls(parent: Doc, child: Doc) {
     const dataDoc = parent[DataSym];
     for (const key of Object.keys(dataDoc)) {
-        key.startsWith("acl") && distributeAcls(key, dataDoc[key], child);
+        // if the default acl mode is private, then don't inherit the acl-Public permission, but set it to private.
+        const permission = (key === "acl-Public" && Doc.UserDoc().defaultAclPrivate) ? AclPrivate : dataDoc[key];
+        key.startsWith("acl") && distributeAcls(key, permission, child);
     }
 }
 
-- 
cgit v1.2.3-70-g09d2


From ed39e4080b79ceba5c358e1359c1a1a44490f0dc Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 10 Aug 2021 10:59:59 -0400
Subject: hideMInimap is playground field.  added Open Alias to dashboard tab
 menu.   Allow duplicates in List fields (not sure if this is problematic but
 caused problems with URL history)

---
 src/client/views/MainView.tsx             | 2 +-
 src/client/views/collections/TreeView.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 3d7446cbe..b0b8d7f41 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -108,7 +108,7 @@ export class MainView extends React.Component {
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
             DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
-                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height",
+                "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
                 "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
         DocServer.GetRefField("rtfProto").then(proto => (proto instanceof Doc) && reaction(() => StrCast(proto.BROADCAST_MESSAGE), msg => msg && alert(msg)));
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index e33c39d20..206e48aac 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -511,7 +511,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             Doc.IsSystem(this.doc) ? [] :
                 this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ?
                     [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, makeFolder] :
-                    [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }];
+                    [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }];
     }
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
 
-- 
cgit v1.2.3-70-g09d2


From 4d21696c1b49c2c383adcd01974c18461123b83c Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 17 Aug 2021 16:55:15 -0400
Subject: made dashboard context menu items context sensitive to whether
 they're called from MyDashboards, MySharedDocs or elsewhere.  Made
 treeViewOpen a playground field so that users don't interfere with each
 other.   Made Docking views not generate alias of their tabs when shared.

---
 src/client/util/CurrentUserUtils.ts                | 35 +++++++++++-----------
 src/client/views/MainView.tsx                      |  2 +-
 .../views/collections/CollectionDockingView.tsx    |  2 +-
 .../views/collections/CollectionTreeView.tsx       | 13 ++++++--
 src/client/views/collections/CollectionView.tsx    | 24 +++++++++------
 src/client/views/collections/TreeView.tsx          | 25 +++++++++++-----
 src/client/views/nodes/DocumentView.tsx            |  2 +-
 7 files changed, 63 insertions(+), 40 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 34990e121..85762a73f 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -765,8 +765,13 @@ export class CurrentUserUtils {
                 _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true
             }));
             const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`);
-            (doc.myDashboards as any as Doc).contextMenuScripts = new List<ScriptField>([newDashboard!]);
-            (doc.myDashboards as any as Doc).contextMenuLabels = new List<string>(["Create New Dashboard"]);
+            const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`);
+            const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
+            const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
+            const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`);
+            const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
+            (doc.myDashboards as any as Doc).childContextMenuScripts = new List<ScriptField>([newDashboard!, toggleTheme!, toggleComic!, snapshotDashboard!, shareDashboard!, removeDashboard!]);
+            (doc.myDashboards as any as Doc).childContextMenuLabels = new List<string>(["Create New Dashboard", "Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Share Dashboard", "Remove Dashboard"]);
         }
         return doc.myDashboards as any as Doc;
     }
@@ -933,6 +938,11 @@ export class CurrentUserUtils {
             }
             if (sharedDocs instanceof Doc) {
                 Doc.GetProto(sharedDocs).userColor = sharedDocs.userColor || "rgb(202, 202, 202)";
+                const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`);
+                const dashboardFilter = ScriptField.MakeFunction(`doc._viewType === '${CollectionViewType.Docking}'`, { doc: Doc.name });
+                sharedDocs.childContextMenuFilters = new List<ScriptField>([dashboardFilter!,]);
+                sharedDocs.childContextMenuScripts = new List<ScriptField>([addToDashboards!,]);
+                sharedDocs.childContextMenuLabels = new List<string>(["Add to Dashboards",]);
             }
             doc.mySharedDocs = new PrefetchProxy(sharedDocs);
         }
@@ -1228,15 +1238,6 @@ export class CurrentUserUtils {
 
         Doc.AddDocToList(myPresentations, "data", presentation);
         userDoc.activePresentation = presentation;
-        const toggleTheme = ScriptField.MakeScript(`Doc.UserDoc().darkScheme = !Doc.UserDoc().darkScheme`);
-        const toggleComic = ScriptField.MakeScript(`toggleComicMode()`);
-        const snapshotDashboard = ScriptField.MakeScript(`snapshotDashboard()`);
-        const createDashboard = ScriptField.MakeScript(`createNewDashboard()`);
-        const shareDashboard = ScriptField.MakeScript(`shareDashboard(self)`);
-        const addToDashboards = ScriptField.MakeScript(`addToDashboards(self)`);
-        const removeDashboard = ScriptField.MakeScript('removeDashboard(self)');
-        dashboardDoc.contextMenuScripts = new List<ScriptField>([toggleTheme!, toggleComic!, snapshotDashboard!, createDashboard!, shareDashboard!, addToDashboards!, removeDashboard!]);
-        dashboardDoc.contextMenuLabels = new List<string>(["Toggle Theme Colors", "Toggle Comic Mode", "Snapshot Dashboard", "Create Dashboard", "Share Dashboard", "Add to Dashboards", "Remove Dashboard"]);
 
         Doc.AddDocToList(dashboards, "data", dashboardDoc);
         CurrentUserUtils.openDashboard(userDoc, dashboardDoc);
@@ -1306,17 +1307,15 @@ Scripting.addGlobal(async function addToDashboards(dashboard: Doc) {
     const allDocs = await DocListCastAsync(dashboard[DataSym]["data-all"]);
 
     // moves the data-all field from the datadoc to the layoutdoc, necessary for off screen docs tab to function properly
-    dashboard["data-all"] = new List<Doc>(allDocs);
-    dashboardAlias["data-all"] = new List<Doc>((allDocs || []).map(doc => Doc.MakeAlias(doc)));
-
-    const dockingConfig = JSON.parse(StrCast(dashboardAlias.dockingConfig));
-    dockingConfig.content = [];
-    dashboardAlias.dockingConfig = JSON.stringify(dockingConfig);
+    // dashboard["data-all"] = new List<Doc>(allDocs);
+    // dashboardAlias["data-all"] = new List<Doc>((allDocs || []).map(doc => Doc.MakeAlias(doc)));
 
+    // const dockingConfig = JSON.parse(StrCast(dashboardAlias.dockingConfig));
+    // dashboardAlias.dockingConfig = JSON.stringify(dockingConfig);
 
     dashboardAlias.data = new List<Doc>(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder)));
     DocListCast(dashboardAlias.data).forEach(doc => doc.dashboard = dashboardAlias);
-    DocListCast(dashboardAlias.data)[0].data = new List<Doc>();
+    //new List<Doc>();
     DocListCast(dashboardAlias.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(self.dashboard)`) as any;
     Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboardAlias);
     CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboardAlias);
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index b0b8d7f41..4d2a0a4c4 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -107,7 +107,7 @@ export class MainView extends React.Component {
         new InkStrokeProperties();
         this._sidebarContent.proto = undefined;
         if (!MainView.Live) {
-            DocServer.setPlaygroundFields(["dataTransition", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
+            DocServer.setPlaygroundFields(["dataTransition", "treeViewOpen", "autoHeight", "showSidebar", "sidebarWidthPercent", "viewTransition",
                 "panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "text-scrollHeight", "text-height", "hideMinimap",
                 "viewScale", "scrollTop", "hidden", "curPage", "viewType", "chromeHidden", "nativeWidth"]); // can play with these fields on someone else's
         }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index c0d39b2a2..cae08e1f4 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -170,7 +170,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
                 const aliasDocList = DocListCast(alias["data-all"]);
                 // if aliasDocList contains the alias, don't do anything
                 // otherwise add the original or an alias depending on whether the doc you're looking at is the current doc or a different alias
-                !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data-all", alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
+                !DocListCast(document.aliases).some(a => aliasDocList.includes(a)) && Doc.AddDocToList(alias, "data-all", document);//alias !== instance.props.Document ? Doc.MakeAlias(document) : document);
             });
         }
         const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName);
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 3eece0086..c0553ca60 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,10 +1,10 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, reaction, IReactionDisposer, observable } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { DataSym, Doc, DocListCast, HeightSym, Opt, WidthSym, StrListCast } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
-import { Document } from '../../../fields/Schema';
+import { Document, listSpec } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
@@ -215,6 +215,11 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
             />
         </div>;
     }
+    childContextMenuItems = () => {
+        const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
+        const filterScripts = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
+        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: filterScripts[i], label }));
+    }
     @computed get treeViewElements() {
         TraceMobx();
         const dropAction = StrCast(this.doc.childDropAction) as dropActionType;
@@ -247,7 +252,9 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
             this.whenChildContentsActiveChanged,
             this.props.dontRegisterView || Cast(this.props.Document.childDontRegisterViews, "boolean", null),
             this.observerHeight,
-            this.unobserveHeight);
+            this.unobserveHeight,
+            this.childContextMenuItems()
+        );
     }
     @computed get titleBar() {
         const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index e65ebf075..a82128e47 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -70,6 +70,7 @@ export interface CollectionViewProps extends FieldViewProps {
     childDocumentsActive?: () => boolean;// whether child documents can be dragged if collection can be dragged (eg., in a when a Pile document is in startburst mode)
     childFitWidth?: () => boolean;
     childOpacity?: () => number;
+    childContextMenuItems?: () => { script: ScriptField, label: string }[];
     childHideTitle?: () => boolean; // whether to hide the documentdecorations title for children
     childHideDecorationTitle?: () => boolean;
     childLayoutTemplate?: () => (Doc | undefined);// specify a layout Doc template to use for children of the collection
@@ -186,15 +187,20 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             }
             !Doc.UserDoc().noviceMode && optionItems.push({ description: `${this.rootDoc.isInPlaceContainer ? "Unset" : "Set"} inPlace Container`, event: () => this.rootDoc.isInPlaceContainer = !this.rootDoc.isInPlaceContainer, icon: "project-diagram" });
 
-            optionItems.push({
-                description: "Create Branch", event: async () => this.props.addDocTab(await BranchCreate(this.rootDoc), "add:right"), icon: "project-diagram"
-            });
-            optionItems.push({
-                description: "Pull Master", event: () => BranchTask(this.rootDoc, "pull"), icon: "project-diagram"
-            });
-            optionItems.push({
-                description: "Merge Branches", event: () => BranchTask(this.rootDoc, "merge"), icon: "project-diagram"
-            });
+            if (!Doc.UserDoc().noviceMode) {
+                optionItems.push({
+                    description: "Create Branch", event: async () => this.props.addDocTab(await BranchCreate(this.rootDoc), "add:right"), icon: "project-diagram"
+                });
+                optionItems.push({
+                    description: "Pull Master", event: () => BranchTask(this.rootDoc, "pull"), icon: "project-diagram"
+                });
+                optionItems.push({
+                    description: "Merge Branches", event: () => BranchTask(this.rootDoc, "merge"), icon: "project-diagram"
+                });
+            }
+            if (this.Document._viewType === CollectionViewType.Docking) {
+                optionItems.push({ description: "Create Dashboard", event: () => CurrentUserUtils.createNewDashboard(Doc.UserDoc()), icon: "project-diagram" });
+            }
 
             !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "hand-point-right" });
 
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 206e48aac..0598be49b 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,7 +1,7 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, WidthSym, StrListCast } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { RichTextField } from '../../../fields/RichTextField';
@@ -54,6 +54,7 @@ export interface TreeViewProps {
     indentDocument?: (editTitle: boolean) => void;
     outdentDocument?: (editTitle: boolean) => void;
     ScreenToLocalTransform: () => Transform;
+    contextMenuItems: { script: ScriptField, filter: ScriptField, label: string }[];
     dontRegisterView?: boolean;
     styleProvider?: StyleProviderFunc | undefined;
     treeViewHideHeaderFields: () => boolean;
@@ -336,7 +337,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                     this.props.dropAction, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.isContentActive,
                     this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields,
                     [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged,
-                    this.props.dontRegisterView, emptyFunction, emptyFunction);
+                    this.props.dontRegisterView, emptyFunction, emptyFunction, this.childContextMenuItems());
             } else {
                 contentElement = <EditableView key="editableView"
                     contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
@@ -418,7 +419,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.titleStyleProvider, this.props.ScreenToLocalTransform,
                         this.props.isContentActive, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields,
                         [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenChildContentsActiveChanged,
-                        this.props.dontRegisterView, emptyFunction, emptyFunction)}
+                        this.props.dontRegisterView, emptyFunction, emptyFunction, this.childContextMenuItems())}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
             return <ul key={this.doc[Id] + this.doc.title}>
@@ -507,11 +508,19 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
     contextMenuItems = () => {
         const makeFolder = { script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" };
-        return this.doc.isFolder ? [makeFolder] :
+        const openAlias = { script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" };
+        const focusDoc = { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" };
+        return [...this.props.contextMenuItems.filter(mi => !mi.filter ? true : mi.filter.script.run({ doc: this.doc })?.result), ... (this.doc.isFolder ? [makeFolder] :
             Doc.IsSystem(this.doc) ? [] :
                 this.props.treeView.fileSysMode && this.doc === Doc.GetProto(this.doc) ?
-                    [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, makeFolder] :
-                    [{ script: ScriptField.MakeFunction(`openOnRight(getAlias(self))`)!, label: "Open Alias" }, { script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }];
+                    [openAlias, makeFolder] :
+                    this.doc.viewType === CollectionViewType.Docking ? [] :
+                        [openAlias, focusDoc])];
+    }
+    childContextMenuItems = () => {
+        const customScripts = Cast(this.doc.childContextMenuScripts, listSpec(ScriptField), []);
+        const customFilters = Cast(this.doc.childContextMenuFilters, listSpec(ScriptField), []);
+        return StrListCast(this.doc.childContextMenuLabels).map((label, i) => ({ script: customScripts[i], filter: customFilters[i], label }));
     }
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
 
@@ -817,7 +826,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         whenChildContentsActiveChanged: (isActive: boolean) => void,
         dontRegisterView: boolean | undefined,
         observerHeight: (ref: any) => void,
-        unobserveHeight: (ref: any) => void
+        unobserveHeight: (ref: any) => void,
+        contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string }[])
     ) {
         const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField);
         if (viewSpecScript) {
@@ -882,6 +892,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 parentTreeView={parentTreeView}
                 observeHeight={observerHeight}
                 unobserveHeight={unobserveHeight}
+                contextMenuItems={contextMenuItems}
             />;
         });
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 745d58656..a29f2f662 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -664,7 +664,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         if (!cm || (e as any)?.nativeEvent?.SchemaHandled) return;
 
         const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
-        Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>
+        StrListCast(this.Document.contextMenuLabels).forEach((label, i) =>
             cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" }));
         this.props.contextMenuItems?.().forEach(item =>
             item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: "sticky-note" }));
-- 
cgit v1.2.3-70-g09d2


From c42f909188aff5398de31e443500eb64b8690ac4 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 26 Aug 2021 08:57:20 -0400
Subject: fixed warnings/errors

---
 src/client/util/SelectionManager.ts                |  2 +-
 src/client/views/MainView.tsx                      |  1 +
 src/client/views/TemplateMenu.tsx                  |  1 +
 .../views/collections/CollectionSchemaView.tsx     |  2 +-
 src/client/views/collections/TreeView.tsx          |  1 +
 .../CollectionFreeFormLinkView.tsx                 |  8 ++--
 .../collections/collectionSchema/SchemaTable.tsx   |  4 +-
 src/client/views/linking/LinkEditor.tsx            |  6 +--
 .../views/linking/LinkRelationshipSearch.tsx       | 12 ++---
 src/client/views/nodes/FilterBox.tsx               |  1 +
 src/client/views/nodes/ImageBox.tsx                |  2 +-
 src/client/views/nodes/LinkBox.tsx                 |  1 +
 src/client/views/pdf/AnchorMenu.tsx                |  2 +-
 src/client/views/pdf/PDFViewer.tsx                 |  2 +-
 src/client/views/search/SearchBox.tsx              | 56 ++++++++++------------
 15 files changed, 50 insertions(+), 51 deletions(-)

(limited to 'src/client/views/MainView.tsx')

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index dbcc49f3d..0cfaebbf2 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,10 +1,10 @@
 import { action, observable, ObservableMap } from "mobx";
 import { computedFn } from "mobx-utils";
 import { Doc, Opt } from "../../fields/Doc";
+import { DocumentType } from "../documents/DocumentTypes";
 import { CollectionSchemaView } from "../views/collections/collectionSchema/CollectionSchemaView";
 import { CollectionViewType } from "../views/collections/CollectionView";
 import { DocumentView } from "../views/nodes/DocumentView";
-import { DocumentType } from "../documents/DocumentTypes";
 
 export namespace SelectionManager {
 
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 6a388c5b4..8b5e18fb2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -473,6 +473,7 @@ export class MainView extends React.Component {
                     bringToFront={emptyFunction}
                     select={emptyFunction}
                     isContentActive={returnFalse}
+                    isAnyChildContentActive={returnFalse}
                     isSelected={returnFalse}
                     docViewPath={returnEmptyDoclist}
                     moveDocument={this.moveButtonDoc}
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 5491a81e6..ff3f92364 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -141,6 +141,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 onCheckedClick={this.scriptField}
                 onChildClick={this.scriptField}
                 dropAction={undefined}
+                isAnyChildContentActive={returnFalse}
                 isContentActive={returnTrue}
                 bringToFront={emptyFunction}
                 focus={emptyFunction}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 1efea96be..6bdeaf722 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -18,6 +18,7 @@ import { SnappingManager } from "../../util/SnappingManager";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
 import { COLLECTION_BORDER_WIDTH, SCHEMA_DIVIDER_WIDTH } from '../../views/global/globalCssVariables.scss';
+import { SchemaTable } from "../collections/collectionSchema/SchemaTable";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import '../DocumentDecorations.scss';
@@ -25,7 +26,6 @@ import { DocumentView } from "../nodes/DocumentView";
 import { DefaultStyleProvider } from "../StyleProvider";
 import "./CollectionSchemaView.scss";
 import { CollectionSubView } from "./CollectionSubView";
-import { SchemaTable } from "../collections/collectionSchema/SchemaTable";
 // bcz: need to add drag and drop of rows and columns.  This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
 
 export enum ColumnType {
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 3ee9dbf59..566083e7e 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -698,6 +698,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             isDocumentActive={asText ? this.props.isContentActive : returnFalse}
             styleProvider={asText ? this.titleStyleProvider : this.embeddedStyleProvider}
             hideTitle={asText}
+            treeViewDoc={this.props.treeView?.props.Document}
             fitContentsToDoc={returnTrue}
             hideDecorationTitle={this.props.treeView.outlineMode}
             hideResizeHandles={this.props.treeView.outlineMode}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index 59891b7a1..16258404d 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -2,15 +2,15 @@ import { action, computed, IReactionDisposer, observable, reaction } from "mobx"
 import { observer } from "mobx-react";
 import { Doc } from "../../../../fields/Doc";
 import { Id } from "../../../../fields/FieldSymbols";
+import { List } from "../../../../fields/List";
 import { NumCast, StrCast } from "../../../../fields/Types";
 import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../Utils';
 import { DocumentType } from "../../../documents/DocumentTypes";
+import { LinkManager } from "../../../util/LinkManager";
 import { SnappingManager } from "../../../util/SnappingManager";
 import { DocumentView } from "../../nodes/DocumentView";
 import "./CollectionFreeFormLinkView.scss";
 import React = require("react");
-import { LinkManager } from "../../../util/LinkManager";
-import { List } from "../../../fields/List";
 
 
 export interface CollectionFreeFormLinkViewProps {
@@ -177,11 +177,11 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
         if (!this.renderData) return (null);
         const { a, b, pt1norm, pt2norm, aActive, bActive, textX, textY, pt1, pt2 } = this.renderData;
         LinkManager.currentLink = this.props.LinkDocs[0];
-        const linkRelationship = LinkManager.currentLink?.linkRelationship; //get string representing relationship
+        const linkRelationship = StrCast(LinkManager.currentLink?.linkRelationship); //get string representing relationship
         const linkRelationshipList = Doc.UserDoc().linkRelationshipList as List<string>;
         const linkColorList = Doc.UserDoc().linkColorList as List<string>;
         //access stroke color using index of the relationship in the color list (default black)
-        const strokeColor = linkRelationshipList.indexOf(linkRelationship) == -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
+        const strokeColor = linkRelationshipList.indexOf(linkRelationship) === -1 ? "black" : linkColorList[linkRelationshipList.indexOf(linkRelationship)];
         return !a.width || !b.width || ((!this.props.LinkDocs[0].linkDisplay) && !aActive && !bActive) ? (null) : (<>
             <path className="collectionfreeformlinkview-linkLine" style={{ opacity: this._opacity, strokeDasharray: "2 2", stroke: strokeColor }}
                 d={`M ${pt1[0]} ${pt1[1]} C ${pt1[0] + pt1norm[0]} ${pt1[1] + pt1norm[1]}, ${pt2[0] + pt2norm[0]} ${pt2[1] + pt2norm[1]}, ${pt2[0]} ${pt2[1]}`} />
diff --git a/src/client/views/collections/collectionSchema/SchemaTable.tsx b/src/client/views/collections/collectionSchema/SchemaTable.tsx
index abe549072..631f623c6 100644
--- a/src/client/views/collections/collectionSchema/SchemaTable.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaTable.tsx
@@ -197,7 +197,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 <div onClick={e => this.changeSorting(col)} style={{ width: 21, padding: 1, display: "inline", zIndex: 1, background: "inherit", cursor: "hand" }}>
                     <FontAwesomeIcon icon={sortIcon} size="lg" />
                 </div>
-                {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+                {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
             </div>;
 
             return {
@@ -562,7 +562,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             onPointerDown={this.props.onPointerDown} onClick={this.props.onClick} onWheel={e => this.props.active(true) && e.stopPropagation()}
             onDrop={e => this.props.onDrop(e, {})} onContextMenu={this.onContextMenu} >
             {this.reactTable}
-            {this.props.Document._chromeHidden || this.props.addDocument == returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
+            {this.props.Document._chromeHidden || this.props.addDocument === returnFalse ? undefined : <div className="collectionSchemaView-addRow" onClick={this.createRow}>+ new</div>}
             {!this._showDoc ? (null) :
                 <div className="collectionSchemaView-documentPreview" ref="overlay"
                     style={{
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index fba95cad2..240a71c3e 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -48,7 +48,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
             if (linkRelationshipList && !linkRelationshipList.includes(value)) {
                 linkRelationshipList.push(value);
                 const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")";
-                linkColorList.push(randColor)
+                linkColorList.push(randColor);
             }
             this.relationshipButtonColor = "rgb(62, 133, 55)";
             setTimeout(action(() => this.relationshipButtonColor = ""), 750);
@@ -62,7 +62,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
     @action
     getRelationshipResults = () => {
         const query = this.relationship; //current content in input box
-        const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList)
+        const linkRelationshipList = StrListCast(Doc.UserDoc().linkRelationshipList);
         if (linkRelationshipList) {
             return linkRelationshipList.filter(rel => rel.includes(query));
         }
@@ -73,7 +73,7 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
      */
     @action
     toggleRelationshipResults = () => {
-        this.relationshipSearchVisibility = this.relationshipSearchVisibility == "none" ? "block" : "none";
+        this.relationshipSearchVisibility = this.relationshipSearchVisibility === "none" ? "block" : "none";
     }
 
     @undoBatch
diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx
index 8f83f0e6e..53da880e4 100644
--- a/src/client/views/linking/LinkRelationshipSearch.tsx
+++ b/src/client/views/linking/LinkRelationshipSearch.tsx
@@ -15,7 +15,7 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
     handleResultClick = (e: React.MouseEvent) => {
         const relationship = (e.target as HTMLParagraphElement).textContent;
         if (relationship) {
-            this.props.handleRelationshipSearchChange(relationship)
+            this.props.handleRelationshipSearchChange(relationship);
         }
     }
 
@@ -31,8 +31,8 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
      * Render an empty div to increase the height of LinkEditor to accommodate 2+ results 
     */
     emptyDiv = () => {
-        if (this.props.results && this.props.results.length > 2 && this.props.display == "block") {
-            return <div style={{ height: "50px" }}></div>
+        if (this.props.results && this.props.results.length > 2 && this.props.display === "block") {
+            return <div style={{ height: "50px" }} />;
         }
     }
 
@@ -47,9 +47,9 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
                     {   // return a dropdown of relationship results if there exist results
                         this.props.results
                             ? this.props.results.map(result => {
-                                return (<p key={result} onClick={this.handleResultClick}>
+                                return <p key={result} onClick={this.handleResultClick}>
                                     {result}
-                                </p>)
+                                </p>;
                             })
                             : <p>No matching relationships</p>
                     }
@@ -58,6 +58,6 @@ export class LinkRelationshipSearch extends React.Component<LinkRelationshipSear
                 {/*Render an empty div to increase the height of LinkEditor to accommodate 2+ results */}
                 {this.emptyDiv()}
             </div>
-        )
+        );
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/FilterBox.tsx b/src/client/views/nodes/FilterBox.tsx
index 1e13d1b5a..7ad03e055 100644
--- a/src/client/views/nodes/FilterBox.tsx
+++ b/src/client/views/nodes/FilterBox.tsx
@@ -417,6 +417,7 @@ export class FilterBox extends ViewBoxBaseComponent<FieldViewProps, FilterBoxDoc
                     renderDepth={1}
                     dropAction={this.props.dropAction}
                     ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                    isAnyChildContentActive={returnFalse}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
                     isSelected={returnFalse}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index b392ddb95..38deb4a73 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -334,7 +334,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     marqueeDown = (e: React.PointerEvent) => {
         if (!e.altKey && e.button === 0 && this.layoutDoc._viewScale === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(CurrentUserUtils.SelectedTool)) {
             setupMoveUpEvents(this, e, action(e => {
-                MarqueeAnnotator.clearAnnotations(this._savedAnnotations)
+                MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
                 this._marqueeing = [e.clientX, e.clientY];
                 return true;
             }), returnFalse, () => MarqueeAnnotator.clearAnnotations(this._savedAnnotations), false);
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index c65ba9c69..55ea45bb8 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -30,6 +30,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps, LinkDocument>(
                 dontRegisterView={true}
                 renderDepth={this.props.renderDepth + 1}
                 CollectionView={undefined}
+                isAnyChildContentActive={returnFalse}
                 isContentActive={this.isContentActiveFunc}
                 addDocument={returnFalse}
                 removeDocument={returnFalse}
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 42bec38da..95e318738 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -69,7 +69,7 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         this._disposer = reaction(() => SelectionManager.Views(),
             selected => {
                 this._showLinkPopup = false;
-                AnchorMenu.Instance.fadeOut(true)
+                AnchorMenu.Instance.fadeOut(true);
             });
     }
 
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index bc35d2126..e77fdde3d 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -525,7 +525,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
                 CollectionView={undefined}
                 ScreenToLocalTransform={this.overlayTransform}
                 renderDepth={this.props.renderDepth + 1}
-                childPointerEvents={true} />
+                childPointerEvents={true} />;
         return <div>
             <div className={`pdfViewerDash-overlay${CurrentUserUtils.SelectedTool !== InkTool.None || SnappingManager.GetIsDragging() ? "-inking" : ""}`}
                 style={{
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 07186fe8d..260ddfc90 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -14,7 +14,7 @@ import "./SearchBox.scss";
 import { DocumentManager } from '../../util/DocumentManager';
 import { DocUtils } from '../../documents/Documents';
 
-export const searchSchema = createSchema({ 
+export const searchSchema = createSchema({
     Document: Doc
 });
 
@@ -109,13 +109,12 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
     });
 
     makeLink = action((linkTo: Doc) => {
-        console.log("[makeLink-1] got here!")
         console.log(linkTo.title);
-        if (this.props.linkFrom){
+        if (this.props.linkFrom) {
             const linkFrom = this.props.linkFrom();
-            if (linkFrom){
+            if (linkFrom) {
                 console.log(linkFrom.title);
-                DocUtils.MakeLink({doc: linkFrom}, {doc:linkTo});
+                DocUtils.MakeLink({ doc: linkFrom }, { doc: linkTo });
             }
         }
     });
@@ -177,10 +176,10 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
      * right side of each search result.
      */
     static formatType(type: String): String {
-        if (type == "pdf") {
+        if (type === "pdf") {
             return "PDF";
         }
-        else if (type == "image") {
+        else if (type === "image") {
             return "Img";
         }
 
@@ -200,28 +199,25 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
         const blockedTypes = [DocumentType.PRESELEMENT, DocumentType.KVP, DocumentType.FILTER, DocumentType.SEARCH, DocumentType.SEARCHITEM, DocumentType.FONTICON, DocumentType.BUTTON, DocumentType.SCRIPTING];
         const blockedKeys = ["x", "y", "proto", "width", "autoHeight", "acl-Override", "acl-Public", "context", "zIndex", "height", "text-scrollHeight", "text-height", "cloneFieldFilter", "isPrototype", "text-annotations",
             "dragFactory-count", "text-noTemplate", "aliases", "system", "layoutKey", "baseProto", "xMargin", "yMargin", "links", "layout", "layout_keyValue", "fitWidth", "viewType", "title-custom",
-            "panX", "panY", "viewScale"]
+            "panX", "panY", "viewScale"];
         const collection = CollectionDockingView.Instance;
         query = query.toLowerCase();
 
-        this._results = []
-        this._selectedResult = undefined
+        this._results = [];
+        this._selectedResult = undefined;
 
         if (collection !== undefined) {
             const docs = DocListCast(collection.rootDoc[Doc.LayoutFieldKey(collection.rootDoc)]);
-            const docIDs: String[] = []
-            console.log(docs.length)
+            const docIDs: String[] = [];
             SearchBox.foreachRecursiveDoc(docs, (depth: number, doc: Doc) => {
                 const dtype = StrCast(doc.type, "string") as DocumentType;
                 if (dtype && !blockedTypes.includes(dtype) && !docIDs.includes(doc[Id]) && depth > 0) {
                     const hlights = new Set<string>();
                     SearchBox.documentKeys(doc).forEach(key => Field.toString(doc[key] as Field).toLowerCase().includes(query) && hlights.add(key));
-                    blockedKeys.forEach(key => {
-                        hlights.delete(key);
-                    })
+                    blockedKeys.forEach(key => hlights.delete(key));
                     Array.from(hlights.keys()).length > 0 && this._results.push([doc, Array.from(hlights.keys())]);
                 }
-                docIDs.push(doc[Id])
+                docIDs.push(doc[Id]);
             });
         }
     }
@@ -245,7 +241,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
     submitSearch = async () => {
         this.resetSearch();
 
-        let query = StrCast(this._searchString);
+        const query = StrCast(this._searchString);
         Doc.SetSearchQuery(query);
         this._results = [];
 
@@ -282,11 +278,9 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
      */
     @computed
     public get selectOptions() {
-        const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"]
+        const selectValues = ["all", "rtf", "image", "pdf", "web", "video", "audio", "collection"];
 
-        return selectValues.map(value => {
-            return <option key={value} value={value}>{SearchBox.formatType(value)}</option>
-        })
+        return selectValues.map(value => <option key={value} value={value}>{SearchBox.formatType(value)}</option>);
     }
 
     /**
@@ -295,17 +289,17 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
     render() {
         var validResults = 0;
 
-        const isLinkSearch:boolean = this.props.linkSearch;
+        const isLinkSearch: boolean = this.props.linkSearch;
 
 
         const results = this._results.map(result => {
             var className = "searchBox-results-scroll-view-result";
 
-            if (this._selectedResult == result[0]) {
-                className += " searchBox-results-scroll-view-result-selected"
+            if (this._selectedResult === result[0]) {
+                className += " searchBox-results-scroll-view-result-selected";
             }
 
-            if (this._docTypeString == "all" || this._docTypeString == result[0].type) {
+            if (this._docTypeString === "all" || this._docTypeString === result[0].type) {
                 validResults++;
                 return (
                     <div key={result[0][Id]} onClick={isLinkSearch ? () => this.makeLink(result[0]) : () => this.onResultClick(result[0])} className={className}>
@@ -319,25 +313,25 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps, SearchBoxDoc
                             {result[1].join(", ")}
                         </div>
                     </div>
-                )
+                );
             }
 
             return null;
-        })
+        });
 
         results.filter(result => result);
 
         return (
             <div style={{ pointerEvents: "all" }} className="searchBox-container">
-                 <div className="searchBox-bar" >
-                 {isLinkSearch ? (null) : <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
+                <div className="searchBox-bar" >
+                    {isLinkSearch ? (null) : <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
                         {this.selectOptions}
                     </select>}
-                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" style={{width: isLinkSearch ? "100%" : undefined, borderRadius: isLinkSearch ? "5px" : undefined}} ref={this._inputRef} />
+                    <input defaultValue={""} autoComplete="off" onChange={this.onInputChange} type="text" placeholder="Search..." id="search-input" className="searchBox-input" style={{ width: isLinkSearch ? "100%" : undefined, borderRadius: isLinkSearch ? "5px" : undefined }} ref={this._inputRef} />
                 </div >
                 <div className="searchBox-results-container">
                     <div className="searchBox-results-count">
-                        {`${validResults}` + " result" + (validResults == 1 ? "" : "s")}
+                        {`${validResults}` + " result" + (validResults === 1 ? "" : "s")}
                     </div>
                     <div className="searchBox-results-scroll-view">
                         {results}
-- 
cgit v1.2.3-70-g09d2

