From eb58759c7304bb9bdce2e1c4804a2e164eb25bcc Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 25 Nov 2019 13:59:54 -0500
Subject: fixes for docking views to reliable show their panes in tree view. 
 fixes for search to fit available space and update properly when scrolled. 
 fixed ymargins on stacking views with titles.

---
 src/client/views/collections/CollectionStackingView.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index be3bfca0a..7d83d5ff3 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -40,7 +40,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
-    @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); }
+    @computed get yMargin() { return Math.max(this.props.Document.showTitle ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
     @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
-- 
cgit v1.2.3-70-g09d2


From bbf482ed6446899bd29e005184ecc779470658c7 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 25 Nov 2019 15:12:55 -0500
Subject: title template fixes for tree/stacking views.

---
 src/client/views/collections/CollectionStackingView.tsx |  6 ++++--
 src/client/views/collections/CollectionTreeView.tsx     | 13 ++++++++-----
 src/client/views/collections/CollectionView.tsx         |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7d83d5ff3..04f57df67 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -41,6 +41,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return Math.max(this.props.Document.showTitle ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
+    @computed get titleSpacing() { return this.props.Document.showTitle ? Math.max(0, NumCast(this.props.Document.yMargin, 2 * this.gridGap) - this.gridGap) : 0; }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
     @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@@ -229,7 +230,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
 
     @computed get columnDragger() {
-        return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px` }} >
+        return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef}
+            style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.titleSpacing)}px` }} >
             <FontAwesomeIcon icon={"arrows-alt-h"} />
         </div>;
     }
@@ -317,7 +319,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         let outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
         let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
         return this.props.ScreenToLocalTransform().
-            translate(offset[0], offset[1] + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0)).
+            translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0)).
             scale(NumCast(doc.width, 1) / this.columnWidth);
     }
 
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8b993820b..261354ba8 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -43,6 +43,7 @@ export interface TreeViewProps {
     pinToPres: (document: Doc) => void;
     panelWidth: () => number;
     panelHeight: () => number;
+    ChromeHeight: undefined | (() => number);
     addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
     indentDocument?: () => void;
     ScreenToLocalTransform: () => Transform;
@@ -233,8 +234,8 @@ class TreeView extends React.Component<TreeViewProps> {
     docTransform = () => {
         let { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
         let outerXf = this.props.outerXf();
-        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
-        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]);
+        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY );
+        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1]+ (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
         return finalXf;
     }
     docWidth = () => {
@@ -272,7 +273,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
                     DocListCast(contents), this.props.treeViewId, doc, undefined, key, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
-                    this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                    this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
                     [...this.props.renderedIds, doc[Id]]);
             } else {
                 contentElement = <EditableView
@@ -305,7 +306,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document),
                         this.templateDataDoc, expandKey, addDoc, remDoc, this.move,
                         this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
-                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
+                        this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.showHeaderFields, this.props.preventTreeViewOpen,
                         [...this.props.renderedIds, this.props.document[Id]])}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
@@ -414,6 +415,7 @@ class TreeView extends React.Component<TreeViewProps> {
         outerXf: () => { translateX: number, translateY: number },
         active: (outsideReaction?: boolean) => boolean,
         panelWidth: () => number,
+        ChromeHeight: undefined| (() => number),
         renderDepth: number,
         showHeaderFields: () => boolean,
         preventTreeViewOpen: boolean,
@@ -487,6 +489,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 addDocument={addDocument}
                 panelWidth={rowWidth}
                 panelHeight={rowHeight}
+                ChromeHeight={ChromeHeight}
                 moveDocument={move}
                 dropAction={dropAction}
                 addDocTab={addDocTab}
@@ -591,7 +594,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                     {
                         TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, addDoc, this.remove,
                             moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
-                            this.outerXf, this.props.active, this.props.PanelWidth, this.props.renderDepth, () => !this.props.Document.hideHeaderFields,
+                            this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => !this.props.Document.hideHeaderFields,
                             BoolCast(this.props.Document.preventTreeViewOpen), [])
                     }
                 </ul>
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 8387e95df..4c49054d2 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -111,7 +111,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     componentWillUnmount = () => this._reactionDisposer && this._reactionDisposer();
 
     // bcz: Argh?  What's the height of the collection chromes??  
-    chromeHeight = () => (this.props.ChromeHeight ? this.props.ChromeHeight() : 0) + (this.props.Document.chromeStatus === "enabled" ? -60 : 0);
+    chromeHeight = () => (this.props.Document.chromeStatus === "enabled" ? -60 : 0);
 
     active = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || BoolCast(this.props.Document.forceActive) || this._isChildActive || this.props.renderDepth === 0;
 
-- 
cgit v1.2.3-70-g09d2


From ef4093854ac9e3b2dadc63ac183792fa49d98f7b Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Mon, 25 Nov 2019 16:21:26 -0500
Subject: cleanup of stacking/masonry and fix so that masonry layout updates
 interactive as docs are resized.

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 129 ++++++++++-----------
 .../views/collections/CollectionStackingView.scss  |   5 +-
 .../views/collections/CollectionStackingView.tsx   |   5 +-
 3 files changed, 69 insertions(+), 70 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 52ebfafd3..df4b00b3a 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -2,7 +2,7 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable } from "mobx";
+import { action, observable, computed } from "mobx";
 import { observer } from "mobx-react";
 import Measure from "react-measure";
 import { Doc } from "../../../new_fields/Doc";
@@ -20,7 +20,6 @@ import { anchorPoints, Flyout } from "../DocumentDecorations";
 import { EditableView } from "../EditableView";
 import { CollectionStackingView } from "./CollectionStackingView";
 import "./CollectionStackingView.scss";
-import { undo } from "prosemirror-history";
 
 library.add(faPalette);
 
@@ -258,12 +257,44 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         }
     }
 
-
-    render() {
+    @computed get contentLayout() {
         let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        let style = this.props.parent; const collapsed = this._collapsed;
+        let chromeStatus = this.props.parent.props.Document.chromeStatus;
+        let newEditableViewProps = {
+            GetValue: () => "",
+            SetValue: this.addDocument,
+            contents: "+ NEW",
+            HeadingObject: this.props.headingObject,
+            HeadingsHack: this._headingsHack,
+            toggle: this.toggleVisibility,
+            color: this._color
+        };
+        return collapsed ? (null) :
+            <div style={{ position: "relative" }}>
+                <div className={`collectionStackingView-masonryGrid`}
+                    ref={this._contRef}
+                    style={{
+                        padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
+                        width: this.props.parent.NodeWidth,
+                        gridGap: this.props.parent.gridGap,
+                        gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
+                    }}>
+                    {this.props.parent.children(this.props.docList)}
+                    {this.props.parent.columnDragger}
+                </div>
+                {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
+                    <div className="collectionStackingView-addDocumentButton"
+                        style={{ width: style.columnWidth / style.numGroupColumns }}>
+                        <EditableView {...newEditableViewProps} />
+                    </div> : null
+                }
+            </div>;
+    }
+
+    @computed get headingView() {
         let heading = this._heading;
-        let style = this.props.parent;
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
         let headerEditableViewProps = {
             GetValue: () => evContents,
@@ -275,30 +306,17 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             toggle: this.toggleVisibility,
             color: this._color
         };
-        let newEditableViewProps = {
-            GetValue: () => "",
-            SetValue: this.addDocument,
-            contents: "+ NEW",
-            HeadingObject: this.props.headingObject,
-            HeadingsHack: this._headingsHack,
-            toggle: this.toggleVisibility,
-            color: this._color
-        };
-        let headingView = this.props.parent.props.Document.miniHeaders ?
-            <div className="collectionStackingView-miniHeader" style={{ width: "100%" }}>
-                {<EditableView {...headerEditableViewProps} />}
+        return this.props.parent.props.Document.miniHeaders ?
+            <div className="collectionStackingView-miniHeader">
+                <EditableView {...headerEditableViewProps} />
             </div> :
-            this.props.headingObject ?
+            !this.props.headingObject ? (null) :
                 <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
                     <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
                         title={evContents === `NO ${key.toUpperCase()} VALUE` ?
                             `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
-                        style={{
-                            width: "100%",
-                            background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
-                            color: "grey"
-                        }}>
-                        {<EditableView {...headerEditableViewProps} />}
+                        style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey", }}>
+                        <EditableView {...headerEditableViewProps} />
                         {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
                             <div className="collectionStackingView-sectionColor">
                                 <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
@@ -321,47 +339,26 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                             </div>
                         }
                     </div>
-                </div > : (null);
+                </div>;
+    }
+    render() {
         const background = this._background; //to account for observables in Measure
-        const collapsed = this._collapsed;
-        let chromeStatus = this.props.parent.props.Document.chromeStatus;
-        return (
-            <Measure offset onResize={this.handleResize}>
-                {({ measureRef }) => {
-                    return <div ref={measureRef}>
-                        <div className="collectionStackingView-masonrySection"
-                            key={heading = "empty"}
-                            style={{ width: this.props.parent.NodeWidth, background }}
-                            ref={this.createRowDropRef}
-                            onPointerEnter={this.pointerEnteredRow}
-                            onPointerLeave={this.pointerLeaveRow}
-                        >
-                            {headingView}
-                            {collapsed ? (null) :
-                                < div style={{ position: "relative" }}>
-                                    <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-                                        ref={this._contRef}
-                                        style={{
-                                            padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
-                                            width: this.props.parent.NodeWidth,
-                                            gridGap: this.props.parent.gridGap,
-                                            gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
-                                        }}>
-                                        {this.props.parent.children(this.props.docList)}
-                                        {this.props.parent.columnDragger}
-                                    </div>
-                                    {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
-                                        <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                                            style={{ width: style.columnWidth / style.numGroupColumns }}>
-                                            <EditableView {...newEditableViewProps} />
-                                        </div> : null
-                                    }
-                                </div>
-                            }
-                        </div >
-                    </div>;
-                }}
-            </Measure>
-        );
+        let contentlayout = this.contentLayout;
+        let headingview = this.headingView;
+        return <Measure offset onResize={this.handleResize}>
+            {({ measureRef }) => {
+                return <div ref={measureRef}>
+                    <div className="collectionStackingView-masonrySection"
+                        style={{ width: this.props.parent.NodeWidth, background }}
+                        ref={this.createRowDropRef}
+                        onPointerEnter={this.pointerEnteredRow}
+                        onPointerLeave={this.pointerLeaveRow}
+                    >
+                        {headingview}
+                        {contentlayout}
+                    </div >
+                </div>;
+            }}
+        </Measure>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 29178b909..e1577cfee 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -97,6 +97,7 @@
 
     .collectionStackingView-columnDoc {
         display: inline-block;
+        margin: auto;
     }
 
     .collectionStackingView-masonryDoc {
@@ -177,7 +178,9 @@
         .collectionStackingView-sectionHeader-subCont {
             outline: none;
             border: 0px;
-            color: $light-color;
+            color: $light-color; 
+            width: 100%;
+            color: grey;
             letter-spacing: 2px;
             font-size: 75%;
             transition: transform 0.2s;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 04f57df67..e564f1193 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -41,7 +41,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return Math.max(this.props.Document.showTitle ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
-    @computed get titleSpacing() { return this.props.Document.showTitle ? Math.max(0, NumCast(this.props.Document.yMargin, 2 * this.gridGap) - this.gridGap) : 0; }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
     @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@@ -65,7 +64,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
             this._docXfs.push({ dxf: dxf, width: width, height: height });
             let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
-            let style = this.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            let style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
                 {this.getDisplayDoc(pair.layout || d, pair.data, dxf, width)}
             </div>;
@@ -231,7 +230,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     @computed get columnDragger() {
         return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef}
-            style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.titleSpacing)}px` }} >
+            style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }} >
             <FontAwesomeIcon icon={"arrows-alt-h"} />
         </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From ef94ad7df2a087141ddb8d347d3e3c484ff7609b Mon Sep 17 00:00:00 2001
From: Sam Wilkins <samwilkins333@gmail.com>
Date: Tue, 3 Dec 2019 01:46:36 -0500
Subject: const linter rule and restored google docs push, fixed routing

---
 package.json                                       |   3 +-
 src/Utils.ts                                       |  91 +++---
 src/client/DocServer.ts                            |  10 +-
 src/client/Network.ts                              |   2 +-
 src/client/apis/GoogleAuthenticationManager.tsx    |   2 +-
 .../apis/google_docs/GoogleApiClientUtils.ts       |  20 +-
 .../apis/google_docs/GooglePhotosClientUtils.ts    |  16 +-
 src/client/apis/youtube/YoutubeBox.tsx             | 102 +++----
 src/client/cognitive_services/CognitiveServices.ts |  50 ++--
 src/client/documents/Documents.ts                  |  80 ++---
 src/client/northstar/dash-fields/HistogramField.ts |   8 +-
 .../model/binRanges/QuantitativeVisualBinRange.ts  |  16 +-
 src/client/northstar/operations/BaseOperation.ts   |  14 +-
 src/client/northstar/utils/MathUtil.ts             |  44 +--
 src/client/util/DictationManager.ts                |  75 +++--
 src/client/util/DocumentManager.ts                 |  28 +-
 src/client/util/DragManager.ts                     |  91 +++---
 src/client/util/DropConverter.ts                   |  10 +-
 src/client/util/History.ts                         |   6 +-
 .../util/Import & Export/DirectoryImportBox.tsx    |  58 ++--
 .../util/Import & Export/ImportMetadataEntry.tsx   |   6 +-
 src/client/util/InteractionUtils.ts                |  18 +-
 src/client/util/LinkManager.ts                     |  62 ++--
 src/client/util/ProsemirrorExampleTransfer.ts      |  50 ++--
 src/client/util/RichTextRules.ts                   |  78 ++---
 src/client/util/RichTextSchema.tsx                 |  86 +++---
 src/client/util/Scripting.ts                       |  38 +--
 src/client/util/SearchUtil.ts                      |  24 +-
 src/client/util/SerializationHelper.ts             |   9 +-
 src/client/util/SharingManager.tsx                 |  13 +-
 src/client/util/TooltipLinkingMenu.tsx             |  22 +-
 src/client/util/TooltipTextMenu.tsx                | 332 ++++++++++-----------
 src/client/util/TypedEvent.ts                      |  62 ++--
 src/client/util/UndoManager.ts                     |  16 +-
 src/client/views/CollectionLinearView.tsx          |  12 +-
 src/client/views/ContextMenu.tsx                   |   6 +-
 src/client/views/ContextMenuItem.tsx               |   2 +-
 src/client/views/DictationOverlay.tsx              |  10 +-
 src/client/views/DocComponent.tsx                  |   5 +-
 src/client/views/DocumentButtonBar.scss            |  32 +-
 src/client/views/DocumentButtonBar.tsx             |  57 ++--
 src/client/views/DocumentDecorations.tsx           |  97 +++---
 src/client/views/GlobalKeyHandler.ts               |  30 +-
 src/client/views/InkSelectDecorations.tsx          |  10 +-
 src/client/views/InkingControl.tsx                 |  26 +-
 src/client/views/InkingStroke.tsx                  |  26 +-
 src/client/views/MainView.tsx                      |  36 +--
 src/client/views/MainViewModal.tsx                 |   6 +-
 src/client/views/MetadataEntryMenu.tsx             |   4 +-
 src/client/views/OverlayView.tsx                   |   6 +-
 src/client/views/PreviewCursor.tsx                 |  12 +-
 src/client/views/ScriptBox.tsx                     |   8 +-
 src/client/views/TemplateMenu.tsx                  |  32 +-
 src/client/views/Touchable.tsx                     |   6 +-
 .../views/collections/CollectionDockingView.tsx    |  92 +++---
 .../collections/CollectionMasonryViewFieldRow.tsx  |  82 ++---
 .../views/collections/CollectionSchemaCells.tsx    |  42 +--
 .../views/collections/CollectionSchemaHeaders.tsx  |  36 ++-
 .../CollectionSchemaMovableTableHOC.tsx            |  62 ++--
 .../views/collections/CollectionSchemaView.tsx     | 118 ++++----
 .../views/collections/CollectionStackingView.tsx   | 120 ++++----
 .../CollectionStackingViewFieldColumn.tsx          |  83 +++---
 .../views/collections/CollectionStaffView.tsx      |   6 +-
 src/client/views/collections/CollectionSubView.tsx |  66 ++--
 .../views/collections/CollectionTreeView.tsx       | 144 ++++-----
 src/client/views/collections/CollectionView.tsx    |  28 +-
 .../views/collections/CollectionViewChromes.tsx    |  67 ++---
 src/client/views/collections/KeyRestrictionRow.tsx |   6 +-
 .../views/collections/ParentDocumentSelector.tsx   |   4 +-
 .../CollectionFreeFormLayoutEngines.tsx            |  10 +-
 .../CollectionFreeFormLinkView.tsx                 |  45 ++-
 .../CollectionFreeFormLinksView.tsx                |   8 +-
 .../CollectionFreeFormRemoteCursors.tsx            |  12 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 231 +++++++-------
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      |   2 +-
 .../collections/collectionFreeForm/MarqueeView.tsx | 137 +++++----
 .../caption_toggle/DetailedCaptionToggle.tsx       |   6 +-
 src/client/views/linking/LinkEditor.tsx            |  82 ++---
 src/client/views/linking/LinkFollowBox.tsx         |  48 +--
 src/client/views/linking/LinkMenu.tsx              |   6 +-
 src/client/views/linking/LinkMenuGroup.tsx         |  22 +-
 src/client/views/linking/LinkMenuItem.tsx          |  14 +-
 src/client/views/nodes/AudioBox.tsx                |  24 +-
 src/client/views/nodes/ButtonBox.tsx               |   8 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  20 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |   4 +-
 src/client/views/nodes/DocuLinkBox.tsx             |  26 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   2 +-
 src/client/views/nodes/DocumentView.tsx            |  72 ++---
 src/client/views/nodes/FaceRectangle.tsx           |   2 +-
 src/client/views/nodes/FaceRectangles.tsx          |   8 +-
 src/client/views/nodes/FontIconBox.tsx             |   8 +-
 src/client/views/nodes/FormattedTextBox.tsx        | 197 ++++++------
 src/client/views/nodes/FormattedTextBoxComment.tsx |  22 +-
 src/client/views/nodes/IconBox.tsx                 |   6 +-
 src/client/views/nodes/ImageBox.tsx                |  86 +++---
 src/client/views/nodes/KeyValueBox.tsx             |  40 +--
 src/client/views/nodes/KeyValuePair.tsx            |   8 +-
 src/client/views/nodes/PDFBox.tsx                  |   8 +-
 src/client/views/nodes/PresBox.tsx                 |  38 +--
 src/client/views/nodes/VideoBox.tsx                |  66 ++--
 src/client/views/nodes/WebBox.tsx                  |  22 +-
 src/client/views/pdf/Annotation.tsx                |  14 +-
 src/client/views/pdf/PDFMenu.tsx                   |   2 +-
 src/client/views/pdf/PDFViewer.tsx                 |  66 ++--
 .../views/presentationview/PresElementBox.tsx      |  12 +-
 src/client/views/search/FilterBox.tsx              |  44 +--
 src/client/views/search/IconButton.tsx             |   2 +-
 src/client/views/search/NaviconButton.tsx          |  22 +-
 src/client/views/search/SearchBox.tsx              |  20 +-
 src/client/views/search/SearchItem.tsx             |  26 +-
 src/client/views/search/ToggleBar.tsx              |   3 +-
 src/debug/Viewer.tsx                               |   4 +-
 src/mobile/ImageUpload.tsx                         |  10 +-
 src/new_fields/Doc.ts                              |  94 +++---
 src/new_fields/List.ts                             |   4 +-
 src/new_fields/RichTextUtils.ts                    |  76 ++---
 src/new_fields/Schema.ts                           |   2 +-
 src/new_fields/ScriptField.ts                      |  10 +-
 src/server/ActionUtilities.ts                      |  29 +-
 src/server/ApiManagers/DownloadManager.ts          |   3 +-
 src/server/ApiManagers/GeneralGoogleManager.ts     |  17 +-
 src/server/ApiManagers/GooglePhotosManager.ts      |   4 +-
 src/server/ApiManagers/PDFManager.ts               |  12 +-
 src/server/ApiManagers/SearchManager.ts            |  12 +-
 src/server/ApiManagers/UploadManager.ts            |  16 +-
 src/server/ApiManagers/UtilManager.ts              |   8 +-
 src/server/DashUploadUtils.ts                      |  12 +-
 src/server/Initialization.ts                       |  15 +-
 src/server/RouteManager.ts                         |  16 +-
 src/server/Websocket/Websocket.ts                  |  15 +-
 src/server/apis/google/GoogleApiServerUtils.ts     |   8 +-
 src/server/authentication/config/passport.ts       |   2 +-
 .../authentication/controllers/user_controller.ts  |   5 +-
 .../authentication/models/current_user_utils.ts    |   6 +-
 src/server/database.ts                             |   4 +-
 src/server/downsize.ts                             |   2 +-
 src/server/index.ts                                |  11 +-
 src/typings/index.d.ts                             |   1 +
 test/test.ts                                       |  18 +-
 tslint.json                                        |  58 ++--
 141 files changed, 2467 insertions(+), 2429 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/package.json b/package.json
index 3725d76eb..499aefdb5 100644
--- a/package.json
+++ b/package.json
@@ -127,6 +127,7 @@
         "child_process": "^1.0.2",
         "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",
@@ -228,4 +229,4 @@
         "xoauth2": "^1.2.0",
         "youtube": "^0.1.0"
     }
-}
+}
\ No newline at end of file
diff --git a/src/Utils.ts b/src/Utils.ts
index 2543743a4..7401ef981 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -54,7 +54,7 @@ export namespace Utils {
     }
 
     export function CopyText(text: string) {
-        var textArea = document.createElement("textarea");
+        const textArea = document.createElement("textarea");
         textArea.value = text;
         document.body.appendChild(textArea);
         textArea.focus();
@@ -66,14 +66,14 @@ export namespace Utils {
     }
 
     export function fromRGBAstr(rgba: string) {
-        let rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
-        let r = rm ? Number(rm[1]) : 0;
-        let gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
-        let g = gm ? Number(gm[1]) : 0;
-        let bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
-        let b = bm ? Number(bm[1]) : 0;
-        let am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
-        let a = am ? Number(am[1]) : 1;
+        const rm = rgba.match(/rgb[a]?\(([ 0-9]+)/);
+        const r = rm ? Number(rm[1]) : 0;
+        const gm = rgba.match(/rgb[a]?\([ 0-9]+,([ 0-9]+)/);
+        const g = gm ? Number(gm[1]) : 0;
+        const bm = rgba.match(/rgb[a]?\([ 0-9]+,[ 0-9]+,([ 0-9]+)/);
+        const b = bm ? Number(bm[1]) : 0;
+        const am = rgba.match(/rgba?\([ 0-9]+,[ 0-9]+,[ 0-9]+,([ .0-9]+)/);
+        const a = am ? Number(am[1]) : 1;
         return { r: r, g: g, b: b, a: a };
     }
 
@@ -86,10 +86,10 @@ export namespace Utils {
         // s /= 100;
         // l /= 100;
 
-        let c = (1 - Math.abs(2 * l - 1)) * s,
+        const c = (1 - Math.abs(2 * l - 1)) * s,
             x = c * (1 - Math.abs((h / 60) % 2 - 1)),
-            m = l - c / 2,
-            r = 0,
+            m = l - c / 2;
+        let r = 0,
             g = 0,
             b = 0;
         if (0 <= h && h < 60) {
@@ -118,10 +118,10 @@ export namespace Utils {
         b /= 255;
 
         // Find greatest and smallest channel values
-        let cmin = Math.min(r, g, b),
+        const cmin = Math.min(r, g, b),
             cmax = Math.max(r, g, b),
-            delta = cmax - cmin,
-            h = 0,
+            delta = cmax - cmin;
+        let h = 0,
             s = 0,
             l = 0;
         // Calculate hue
@@ -173,11 +173,11 @@ export namespace Utils {
     function project(px: number, py: number, ax: number, ay: number, bx: number, by: number) {
 
         if (ax === bx && ay === by) return { point: { x: ax, y: ay }, left: false, dot: 0, t: 0 };
-        var atob = { x: bx - ax, y: by - ay };
-        var atop = { x: px - ax, y: py - ay };
-        var len = atob.x * atob.x + atob.y * atob.y;
+        const atob = { x: bx - ax, y: by - ay };
+        const atop = { x: px - ax, y: py - ay };
+        const len = atob.x * atob.x + atob.y * atob.y;
         var dot = atop.x * atob.x + atop.y * atob.y;
-        var t = Math.min(1, Math.max(0, dot / len));
+        const t = Math.min(1, Math.max(0, dot / len));
 
         dot = (bx - ax) * (py - ay) - (by - ay) * (px - ax);
 
@@ -195,38 +195,38 @@ export namespace Utils {
     export function closestPtBetweenRectangles(l: number, t: number, w: number, h: number,
         l1: number, t1: number, w1: number, h1: number,
         x: number, y: number) {
-        var r = l + w,
+        const r = l + w,
             b = t + h;
-        var r1 = l1 + w1,
+        const r1 = l1 + w1,
             b1 = t1 + h1;
-        let hsegs = [[l, r, t, l1, r1, t1], [l, r, b, l1, r1, t1], [l, r, t, l1, r1, b1], [l, r, b, l1, r1, b1]];
-        let vsegs = [[l, t, b, l1, t1, b1], [r, t, b, l1, t1, b1], [l, t, b, r1, t1, b1], [r, t, b, r1, t1, b1]];
-        let res = hsegs.reduce((closest, seg) => {
-            let res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+        const hsegs = [[l, r, t, l1, r1, t1], [l, r, b, l1, r1, t1], [l, r, t, l1, r1, b1], [l, r, b, l1, r1, b1]];
+        const vsegs = [[l, t, b, l1, t1, b1], [r, t, b, l1, t1, b1], [l, t, b, r1, t1, b1], [r, t, b, r1, t1, b1]];
+        const res = hsegs.reduce((closest, seg) => {
+            const res = distanceBetweenHorizontalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
             return (res[0] < closest[0]) ? res : closest;
         }, [Number.MAX_VALUE, []] as [number, number[]]);
-        let fres = vsegs.reduce((closest, seg) => {
-            let res = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
+        const fres = vsegs.reduce((closest, seg) => {
+            const res = distanceBetweenVerticalLines(seg[0], seg[1], seg[2], seg[3], seg[4], seg[5]);
             return (res[0] < closest[0]) ? res : closest;
         }, res);
 
-        let near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
+        const near = project(x, y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
         return project(near.point.x, near.point.y, fres[1][0], fres[1][1], fres[1][2], fres[1][3]);
     }
 
     export function getNearestPointInPerimeter(l: number, t: number, w: number, h: number, x: number, y: number) {
-        var r = l + w,
+        const r = l + w,
             b = t + h;
 
-        var x = clamp(x, l, r),
+        x = clamp(x, l, r),
             y = clamp(y, t, b);
 
-        var dl = Math.abs(x - l),
+        const dl = Math.abs(x - l),
             dr = Math.abs(x - r),
             dt = Math.abs(y - t),
             db = Math.abs(y - b);
 
-        var m = Math.min(dl, dr, dt, db);
+        const m = Math.min(dl, dr, dt, db);
 
         return (m === dt) ? [x, t] :
             (m === db) ? [x, b] :
@@ -234,7 +234,7 @@ export namespace Utils {
     }
 
     export function GetClipboardText(): string {
-        var textArea = document.createElement("textarea");
+        const textArea = document.createElement("textarea");
         document.body.appendChild(textArea);
         textArea.focus();
         textArea.select();
@@ -257,7 +257,7 @@ export namespace Utils {
         if (logFilter !== undefined && logFilter !== message.type) {
             return;
         }
-        let idString = (message.id || "").padStart(36, ' ');
+        const idString = (message.id || "").padStart(36, ' ');
         prefix = prefix.padEnd(16, ' ');
         console.log(`${prefix}: ${idString}, ${receiving ? 'receiving' : 'sending'} ${messageName} with data ${JSON.stringify(message)} `);
     }
@@ -309,18 +309,18 @@ export function OmitKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => vo
 }
 
 export function WithKeys(obj: any, keys: string[], addKeyFunc?: (dup: any) => void) {
-    var dup: any = {};
+    const dup: any = {};
     keys.forEach(key => dup[key] = obj[key]);
     addKeyFunc && addKeyFunc(dup);
     return dup;
 }
 
 export function timenow() {
-    var now = new Date();
+    const now = new Date();
     let ampm = 'am';
     let h = now.getHours();
     let m: any = now.getMinutes();
-    let s: any = now.getSeconds();
+    const s: any = now.getSeconds();
     if (h >= 12) {
         if (h > 12) h -= 12;
         ampm = 'pm';
@@ -331,8 +331,8 @@ export function timenow() {
 
 export function aggregateBounds(boundsList: { x: number, y: number, width: number, height: number }[]) {
     return boundsList.reduce((bounds, b) => {
-        var [sptX, sptY] = [b.x, b.y];
-        let [bptX, bptY] = [sptX + b.width, sptY + b.height];
+        const [sptX, sptY] = [b.x, b.y];
+        const [bptX, bptY] = [sptX + b.width, sptY + b.height];
         return {
             x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
             r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
@@ -371,10 +371,11 @@ export type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
 export type Predicate<K, V> = (entry: [K, V]) => boolean;
 
 export function DeepCopy<K, V>(source: Map<K, V>, predicate?: Predicate<K, V>) {
-    let deepCopy = new Map<K, V>();
-    let entries = source.entries(), next = entries.next();
+    const deepCopy = new Map<K, V>();
+    const entries = source.entries();
+    let next = entries.next();
     while (!next.done) {
-        let entry = next.value;
+        const entry = next.value;
         if (!predicate || predicate(entry)) {
             deepCopy.set(entry[0], entry[1]);
         }
@@ -427,13 +428,13 @@ export function smoothScroll(duration: number, element: HTMLElement, to: number)
     animateScroll();
 }
 export function addStyleSheet(styleType: string = "text/css") {
-    let style = document.createElement("style");
+    const style = document.createElement("style");
     style.type = styleType;
-    var sheets = document.head.appendChild(style);
+    const sheets = document.head.appendChild(style);
     return (sheets as any).sheet;
 }
 export function addStyleSheetRule(sheet: any, selector: any, css: any) {
-    var propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";");
+    const propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";");
     return sheet.insertRule("." + selector + "{" + propText + "}", sheet.cssRules.length);
 }
 export function removeStyleSheetRule(sheet: any, rule: number) {
diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts
index 2cec1046b..e4b183715 100644
--- a/src/client/DocServer.ts
+++ b/src/client/DocServer.ts
@@ -1,5 +1,5 @@
 import * as OpenSocket from 'socket.io-client';
-import { MessageStore, Diff, YoutubeQueryTypes } from "./../server/Message";
+import { MessageStore, YoutubeQueryTypes } from "./../server/Message";
 import { Opt, Doc } from '../new_fields/Doc';
 import { Utils, emptyFunction } from '../Utils';
 import { SerializationHelper } from './util/SerializationHelper';
@@ -148,7 +148,7 @@ export namespace DocServer {
         // an initial pass through the cache to determine whether the document needs to be fetched,
         // is already in the process of being fetched or already exists in the
         // cache
-        let cached = _cache[id];
+        const cached = _cache[id];
         if (cached === undefined) {
             // NOT CACHED => we'll have to send a request to the server
 
@@ -195,7 +195,7 @@ export namespace DocServer {
     }
 
     export async function getYoutubeChannels() {
-        let apiKey = await Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels });
+        const apiKey = await Utils.EmitCallback(_socket, MessageStore.YoutubeApiQuery, { type: YoutubeQueryTypes.Channels });
         return apiKey;
     }
 
@@ -255,7 +255,7 @@ export namespace DocServer {
             for (const field of fields) {
                 if (field !== undefined) {
                     // deserialize
-                    let prom = SerializationHelper.Deserialize(field).then(deserialized => {
+                    const prom = SerializationHelper.Deserialize(field).then(deserialized => {
                         fieldMap[field.id] = deserialized;
 
                         //overwrite or delete any promises (that we inserted as flags
@@ -411,7 +411,7 @@ export namespace DocServer {
     }
 
     let _RespondToUpdate = _respondToUpdateImpl;
-    let _respondToDelete = _respondToDeleteImpl;
+    const _respondToDelete = _respondToDeleteImpl;
 
     function respondToUpdate(diff: any) {
         _RespondToUpdate(diff);
diff --git a/src/client/Network.ts b/src/client/Network.ts
index f9ef27267..ccf60f199 100644
--- a/src/client/Network.ts
+++ b/src/client/Network.ts
@@ -8,7 +8,7 @@ export namespace Networking {
     }
 
     export async function PostToServer(relativeRoute: string, body?: any) {
-        let options = {
+        const options = {
             uri: Utils.prepend(relativeRoute),
             method: "POST",
             body,
diff --git a/src/client/apis/GoogleAuthenticationManager.tsx b/src/client/apis/GoogleAuthenticationManager.tsx
index ae77c4b7b..ce1277667 100644
--- a/src/client/apis/GoogleAuthenticationManager.tsx
+++ b/src/client/apis/GoogleAuthenticationManager.tsx
@@ -30,7 +30,7 @@ export default class GoogleAuthenticationManager extends React.Component<{}> {
     }
 
     public fetchOrGenerateAccessToken = async () => {
-        let response = await Networking.FetchFromServer("/readGoogleAccessToken");
+        const response = await Networking.FetchFromServer("/readGoogleAccessToken");
         // if this is an authentication url, activate the UI to register the new access token
         if (new RegExp(AuthenticationUrl).test(response)) {
             this.isOpen = true;
diff --git a/src/client/apis/google_docs/GoogleApiClientUtils.ts b/src/client/apis/google_docs/GoogleApiClientUtils.ts
index 26c7f8d2e..d2a79f189 100644
--- a/src/client/apis/google_docs/GoogleApiClientUtils.ts
+++ b/src/client/apis/google_docs/GoogleApiClientUtils.ts
@@ -1,4 +1,4 @@
-import { docs_v1, slides_v1 } from "googleapis";
+import { docs_v1 } from "googleapis";
 import { Opt } from "../../../new_fields/Doc";
 import { isArray } from "util";
 import { EditorState } from "prosemirror-state";
@@ -94,7 +94,7 @@ export namespace GoogleApiClientUtils {
 
             export type ExtractResult = { text: string, paragraphs: DeconstructedParagraph[] };
             export const extractText = (document: docs_v1.Schema$Document, removeNewlines = false): ExtractResult => {
-                let paragraphs = extractParagraphs(document);
+                const paragraphs = extractParagraphs(document);
                 let text = paragraphs.map(paragraph => paragraph.contents.filter(content => !("inlineObjectId" in content)).map(run => run as docs_v1.Schema$TextRun).join("")).join("");
                 text = text.substring(0, text.length - 1);
                 removeNewlines && text.ReplaceAll("\n", "");
@@ -107,14 +107,14 @@ export namespace GoogleApiClientUtils {
                 const fragments: DeconstructedParagraph[] = [];
                 if (document.body && document.body.content) {
                     for (const element of document.body.content) {
-                        let runs: ContentArray = [];
+                        const runs: ContentArray = [];
                         let bullet: Opt<number>;
                         if (element.paragraph) {
                             if (element.paragraph.elements) {
                                 for (const inner of element.paragraph.elements) {
                                     if (inner) {
                                         if (inner.textRun) {
-                                            let run = inner.textRun;
+                                            const run = inner.textRun;
                                             (run.content || !filterEmpty) && runs.push(inner.textRun);
                                         } else if (inner.inlineObjectElement) {
                                             runs.push(inner.inlineObjectElement);
@@ -182,8 +182,8 @@ export namespace GoogleApiClientUtils {
         export const read = async (options: ReadOptions): Promise<Opt<ReadResult>> => {
             return retrieve({ documentId: options.documentId }).then(document => {
                 if (document) {
-                    let title = document.title!;
-                    let body = Utils.extractText(document, options.removeNewlines).text;
+                    const title = document.title!;
+                    const body = Utils.extractText(document, options.removeNewlines).text;
                     return { title, body };
                 }
             });
@@ -192,7 +192,7 @@ export namespace GoogleApiClientUtils {
         export const readLines = async (options: ReadOptions): Promise<Opt<ReadLinesResult>> => {
             return retrieve({ documentId: options.documentId }).then(document => {
                 if (document) {
-                    let title = document.title;
+                    const title = document.title;
                     let bodyLines = Utils.extractText(document).text.split("\n");
                     options.removeNewlines && (bodyLines = bodyLines.filter(line => line.length));
                     return { title, bodyLines };
@@ -201,7 +201,7 @@ export namespace GoogleApiClientUtils {
         };
 
         export const setStyle = async (options: UpdateOptions) => {
-            let replies: any = await update({
+            const replies: any = await update({
                 documentId: options.documentId,
                 requests: options.requests
             });
@@ -221,7 +221,7 @@ export namespace GoogleApiClientUtils {
             let index = options.index;
             const mode = options.mode;
             if (!(index && mode === WriteMode.Insert)) {
-                let schema = await retrieve({ documentId });
+                const schema = await retrieve({ documentId });
                 if (!schema || !(index = Utils.endOf(schema))) {
                     return undefined;
                 }
@@ -248,7 +248,7 @@ export namespace GoogleApiClientUtils {
                 return undefined;
             }
             requests.push(...options.content.requests);
-            let replies: any = await update({ documentId: documentId, requests });
+            const replies: any = await update({ documentId: documentId, requests });
             if ("errors" in replies) {
                 console.log("Write operation failed:");
                 console.log(replies.errors.map((error: any) => error.message));
diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index bf8897061..966d8053a 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -128,10 +128,10 @@ export namespace GooglePhotos {
 
         export const CollectionFromSearch = async (constructor: CollectionConstructor, requested: Opt<Partial<Query.SearchOptions>>): Promise<Doc> => {
             await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
-            let response = await Query.ContentSearch(requested);
-            let uploads = await Transactions.WriteMediaItemsToServer(response);
+            const response = await Query.ContentSearch(requested);
+            const uploads = await Transactions.WriteMediaItemsToServer(response);
             const children = uploads.map((upload: Transactions.UploadInformation) => {
-                let document = Docs.Create.ImageDocument(Utils.fileUrl(upload.fileNames.clean));
+                const document = Docs.Create.ImageDocument(Utils.fileUrl(upload.fileNames.clean));
                 document.fillColumn = true;
                 document.contentSize = upload.contentSize;
                 return document;
@@ -157,12 +157,12 @@ export namespace GooglePhotos {
             const images = (await DocListCastAsync(collection.data))!.map(Doc.GetProto);
             images && images.forEach(image => tagMapping.set(image[Id], ContentCategories.NONE));
             const values = Object.values(ContentCategories);
-            for (let value of values) {
+            for (const value of values) {
                 if (value !== ContentCategories.NONE) {
                     const results = await ContentSearch({ included: [value] });
                     if (results.mediaItems) {
                         const ids = results.mediaItems.map(item => item.id);
-                        for (let id of ids) {
+                        for (const id of ids) {
                             const image = await Cast(idMapping[id], Doc);
                             if (image) {
                                 const key = image[Id];
@@ -220,9 +220,9 @@ export namespace GooglePhotos {
 
         export const AlbumSearch = async (albumId: string, pageSize = 100): Promise<MediaItem[]> => {
             const photos = await endpoint();
-            let mediaItems: MediaItem[] = [];
+            const mediaItems: MediaItem[] = [];
             let nextPageTokenStored: Opt<string> = undefined;
-            let found = 0;
+            const found = 0;
             do {
                 const response: any = await photos.mediaItems.search(albumId, pageSize, nextPageTokenStored);
                 mediaItems.push(...response.mediaItems);
@@ -332,7 +332,7 @@ export namespace GooglePhotos {
                 album = await Create.Album(album.title);
             }
             const media: MediaInput[] = [];
-            for (let source of sources) {
+            for (const source of sources) {
                 const data = Cast(Doc.GetProto(source).data, ImageField);
                 if (!data) {
                     return;
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
index bed812852..fd3d9e2f1 100644
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -48,44 +48,44 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
      */
     async componentWillMount() {
         //DocServer.getYoutubeChannels();
-        let castedSearchBackUp = Cast(this.props.Document.cachedSearchResults, Doc);
-        let awaitedBackUp = await castedSearchBackUp;
-        let castedDetailBackUp = Cast(this.props.Document.cachedDetails, Doc);
-        let awaitedDetails = await castedDetailBackUp;
+        const castedSearchBackUp = Cast(this.props.Document.cachedSearchResults, Doc);
+        const awaitedBackUp = await castedSearchBackUp;
+        const castedDetailBackUp = Cast(this.props.Document.cachedDetails, Doc);
+        const awaitedDetails = await castedDetailBackUp;
 
 
         if (awaitedBackUp) {
 
 
-            let jsonList = await DocListCastAsync(awaitedBackUp.json);
-            let jsonDetailList = await DocListCastAsync(awaitedDetails!.json);
+            const jsonList = await DocListCastAsync(awaitedBackUp.json);
+            const jsonDetailList = await DocListCastAsync(awaitedDetails!.json);
 
             if (jsonList!.length !== 0) {
                 runInAction(() => this.searchResultsFound = true);
                 let index = 0;
                 //getting the necessary information from backUps and building templates that will be used to map in render
-                for (let video of jsonList!) {
-
-                    let videoId = await Cast(video.id, Doc);
-                    let id = StrCast(videoId!.videoId);
-                    let snippet = await Cast(video.snippet, Doc);
-                    let videoTitle = this.filterYoutubeTitleResult(StrCast(snippet!.title));
-                    let thumbnail = await Cast(snippet!.thumbnails, Doc);
-                    let thumbnailMedium = await Cast(thumbnail!.medium, Doc);
-                    let thumbnailUrl = StrCast(thumbnailMedium!.url);
-                    let videoDescription = StrCast(snippet!.description);
-                    let pusblishDate = (this.roundPublishTime(StrCast(snippet!.publishedAt)))!;
-                    let channelTitle = StrCast(snippet!.channelTitle);
+                for (const video of jsonList!) {
+
+                    const videoId = await Cast(video.id, Doc);
+                    const id = StrCast(videoId!.videoId);
+                    const snippet = await Cast(video.snippet, Doc);
+                    const videoTitle = this.filterYoutubeTitleResult(StrCast(snippet!.title));
+                    const thumbnail = await Cast(snippet!.thumbnails, Doc);
+                    const thumbnailMedium = await Cast(thumbnail!.medium, Doc);
+                    const thumbnailUrl = StrCast(thumbnailMedium!.url);
+                    const videoDescription = StrCast(snippet!.description);
+                    const pusblishDate = (this.roundPublishTime(StrCast(snippet!.publishedAt)))!;
+                    const channelTitle = StrCast(snippet!.channelTitle);
                     let duration: string = "";
                     let viewCount: string = "";
                     if (jsonDetailList!.length !== 0) {
-                        let contentDetails = await Cast(jsonDetailList![index].contentDetails, Doc);
-                        let statistics = await Cast(jsonDetailList![index].statistics, Doc);
+                        const contentDetails = await Cast(jsonDetailList![index].contentDetails, Doc);
+                        const statistics = await Cast(jsonDetailList![index].statistics, Doc);
                         duration = this.convertIsoTimeToDuration(StrCast(contentDetails!.duration));
                         viewCount = this.abbreviateViewCount(parseInt(StrCast(statistics!.viewCount)))!;
                     }
                     index = index + 1;
-                    let newTemplate: VideoTemplate = { videoId: id, videoTitle: videoTitle, thumbnailUrl: thumbnailUrl, publishDate: pusblishDate, channelTitle: channelTitle, videoDescription: videoDescription, duration: duration, viewCount: viewCount };
+                    const newTemplate: VideoTemplate = { videoId: id, videoTitle: videoTitle, thumbnailUrl: thumbnailUrl, publishDate: pusblishDate, channelTitle: channelTitle, videoDescription: videoDescription, duration: duration, viewCount: viewCount };
                     runInAction(() => this.curVideoTemplates.push(newTemplate));
                 }
             }
@@ -115,7 +115,7 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
      */
     onEnterKeyDown = (e: React.KeyboardEvent) => {
         if (e.keyCode === 13) {
-            let submittedTitle = this.YoutubeSearchElement!.value;
+            const submittedTitle = this.YoutubeSearchElement!.value;
             this.YoutubeSearchElement!.value = "";
             this.YoutubeSearchElement!.blur();
             DocServer.getYoutubeVideos(submittedTitle, this.processesVideoResults);
@@ -184,23 +184,23 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
      * difference between today's date and that date, in terms of "ago" to imitate youtube.
      */
     roundPublishTime = (publishTime: string) => {
-        let date = new Date(publishTime).getTime();
-        let curDate = new Date().getTime();
-        let timeDif = curDate - date;
-        let totalSeconds = timeDif / 1000;
-        let totalMin = totalSeconds / 60;
-        let totalHours = totalMin / 60;
-        let totalDays = totalHours / 24;
-        let totalMonths = totalDays / 30.417;
-        let totalYears = totalMonths / 12;
-
-
-        let truncYears = Math.trunc(totalYears);
-        let truncMonths = Math.trunc(totalMonths);
-        let truncDays = Math.trunc(totalDays);
-        let truncHours = Math.trunc(totalHours);
-        let truncMin = Math.trunc(totalMin);
-        let truncSec = Math.trunc(totalSeconds);
+        const date = new Date(publishTime).getTime();
+        const curDate = new Date().getTime();
+        const timeDif = curDate - date;
+        const totalSeconds = timeDif / 1000;
+        const totalMin = totalSeconds / 60;
+        const totalHours = totalMin / 60;
+        const totalDays = totalHours / 24;
+        const totalMonths = totalDays / 30.417;
+        const totalYears = totalMonths / 12;
+
+
+        const truncYears = Math.trunc(totalYears);
+        const truncMonths = Math.trunc(totalMonths);
+        const truncDays = Math.trunc(totalDays);
+        const truncHours = Math.trunc(totalHours);
+        const truncMin = Math.trunc(totalMin);
+        const truncSec = Math.trunc(totalSeconds);
 
         let pluralCase = "";
 
@@ -230,7 +230,7 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
      */
     convertIsoTimeToDuration = (isoDur: string) => {
 
-        let convertedTime = isoDur.replace(/D|H|M/g, ":").replace(/P|T|S/g, "").split(":");
+        const convertedTime = isoDur.replace(/D|H|M/g, ":").replace(/P|T|S/g, "").split(":");
 
         if (1 === convertedTime.length) {
             2 !== convertedTime[0].length && (convertedTime[0] = "0" + convertedTime[0]), convertedTime[0] = "0:" + convertedTime[0];
@@ -269,10 +269,10 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
             if (this.searchResults.length !== 0) {
                 return <ul>
                     {this.searchResults.map((video, index) => {
-                        let filteredTitle = this.filterYoutubeTitleResult(video.snippet.title);
-                        let channelTitle = video.snippet.channelTitle;
-                        let videoDescription = video.snippet.description;
-                        let pusblishDate = this.roundPublishTime(video.snippet.publishedAt);
+                        const filteredTitle = this.filterYoutubeTitleResult(video.snippet.title);
+                        const channelTitle = video.snippet.channelTitle;
+                        const videoDescription = video.snippet.description;
+                        const pusblishDate = this.roundPublishTime(video.snippet.publishedAt);
                         let duration;
                         let viewCount;
                         if (this.videoDetails.length !== 0) {
@@ -331,26 +331,26 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
      */
     @action
     embedVideoOnClick = (videoId: string, filteredTitle: string) => {
-        let embeddedUrl = "https://www.youtube.com/embed/" + videoId;
+        const embeddedUrl = "https://www.youtube.com/embed/" + videoId;
         this.selectedVideoUrl = embeddedUrl;
-        let addFunction = this.props.addDocument!;
-        let newVideoX = NumCast(this.props.Document.x);
-        let newVideoY = NumCast(this.props.Document.y) + NumCast(this.props.Document.height);
+        const addFunction = this.props.addDocument!;
+        const newVideoX = NumCast(this.props.Document.x);
+        const newVideoY = NumCast(this.props.Document.y) + NumCast(this.props.Document.height);
 
         addFunction(Docs.Create.VideoDocument(embeddedUrl, { title: filteredTitle, width: 400, height: 315, x: newVideoX, y: newVideoY }));
         this.videoClicked = true;
     }
 
     render() {
-        let content =
+        const content =
             <div className="youtubeBox-cont" style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 <input type="text" placeholder="Search for a video" onKeyDown={this.onEnterKeyDown} style={{ height: 40, width: "100%", border: "1px solid black", padding: 5, textAlign: "center" }} ref={(e) => this.YoutubeSearchElement = e!} />
                 {this.renderSearchResultsOrVideo()}
             </div>;
 
-        let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
+        const frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
 
-        let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
+        const classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
         return (
             <>
                 <div className={classname}  >
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index 5a7f5e991..02eff3b25 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -1,5 +1,5 @@
 import * as request from "request-promise";
-import { Doc, Field, Opt } from "../../new_fields/Doc";
+import { Doc, Field } from "../../new_fields/Doc";
 import { Cast } from "../../new_fields/Types";
 import { Docs } from "../documents/Documents";
 import { Utils } from "../../Utils";
@@ -101,14 +101,14 @@ export namespace CognitiveServices {
         export namespace Appliers {
 
             export const ProcessImage: AnalysisApplier<string> = async (target: Doc, keys: string[], url: string, service: Service, converter: Converter) => {
-                let batch = UndoManager.StartBatch("Image Analysis");
+                const batch = UndoManager.StartBatch("Image Analysis");
 
-                let storageKey = keys[0];
+                const storageKey = keys[0];
                 if (!url || await Cast(target[storageKey], Doc)) {
                     return;
                 }
                 let toStore: any;
-                let results = await ExecuteQuery(service, Manager, url);
+                const results = await ExecuteQuery(service, Manager, url);
                 if (!results) {
                     toStore = "Cognitive Services could not process the given image URL.";
                 } else {
@@ -131,36 +131,32 @@ export namespace CognitiveServices {
 
     export namespace Inking {
 
-        export const Manager: APIManager<InkData> = {
-
-            converter: (inkData: InkData): string => {
-                let entries = inkData.entries(), next = entries.next();
-                let strokes: AzureStrokeData[] = [], id = 0;
-                while (!next.done) {
-                    strokes.push({
-                        id: id++,
-                        points: next.value[1].pathData.map(point => `${point.x},${point.y}`).join(","),
-                        language: "en-US"
-                    });
-                    next = entries.next();
-                }
+        export const Manager: APIManager<InkData[]> = {
+
+            converter: (inkData: InkData[]): string => {
+                let id = 0;
+                const strokes: AzureStrokeData[] = inkData.map(points => ({
+                    id: id++,
+                    points: points.map(({ x, y }) => `${x},${y}`).join(","),
+                    language: "en-US"
+                }));
                 return JSON.stringify({
                     version: 1,
                     language: "en-US",
                     unit: "mm",
-                    strokes: strokes
+                    strokes
                 });
             },
 
             requester: async (apiKey: string, body: string) => {
-                let xhttp = new XMLHttpRequest();
-                let serverAddress = "https://api.cognitive.microsoft.com";
-                let endpoint = serverAddress + "/inkrecognizer/v1.0-preview/recognize";
+                const xhttp = new XMLHttpRequest();
+                const serverAddress = "https://api.cognitive.microsoft.com";
+                const endpoint = serverAddress + "/inkrecognizer/v1.0-preview/recognize";
 
-                let promisified = (resolve: any, reject: any) => {
+                const promisified = (resolve: any, reject: any) => {
                     xhttp.onreadystatechange = function () {
                         if (this.readyState === 4) {
-                            let result = xhttp.responseText;
+                            const result = xhttp.responseText;
                             switch (this.status) {
                                 case 200:
                                     return resolve(result);
@@ -184,15 +180,15 @@ export namespace CognitiveServices {
 
         export namespace Appliers {
 
-            export const ConcatenateHandwriting: AnalysisApplier<InkData> = async (target: Doc, keys: string[], inkData: InkData) => {
-                let batch = UndoManager.StartBatch("Ink Analysis");
+            export const ConcatenateHandwriting: AnalysisApplier<InkData[]> = async (target: Doc, keys: string[], inkData: InkData[]) => {
+                const batch = UndoManager.StartBatch("Ink Analysis");
 
                 let results = await ExecuteQuery(Service.Handwriting, Manager, inkData);
                 if (results) {
                     results.recognitionUnits && (results = results.recognitionUnits);
                     target[keys[0]] = Docs.Get.DocumentHierarchyFromJson(results, "Ink Analysis");
-                    let recognizedText = results.map((item: any) => item.recognizedText);
-                    let individualWords = recognizedText.filter((text: string) => text && text.split(" ").length === 1);
+                    const recognizedText = results.map((item: any) => item.recognizedText);
+                    const individualWords = recognizedText.filter((text: string) => text && text.split(" ").length === 1);
                     target[keys[1]] = individualWords.join(" ");
                 }
 
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d1e3ea708..e0f2858ba 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -35,10 +35,10 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie
 import { LinkManager } from "../util/LinkManager";
 import { DocumentManager } from "../util/DocumentManager";
 import DirectoryImportBox from "../util/Import & Export/DirectoryImportBox";
-import { Scripting, CompileScript } from "../util/Scripting";
+import { Scripting } from "../util/Scripting";
 import { ButtonBox } from "../views/nodes/ButtonBox";
 import { FontIconBox } from "../views/nodes/FontIconBox";
-import { SchemaHeaderField, RandomPastel } from "../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
 import { PresBox } from "../views/nodes/PresBox";
 import { ComputedField, ScriptField } from "../../new_fields/ScriptField";
 import { ProxyField } from "../../new_fields/Proxy";
@@ -50,8 +50,8 @@ import { ColorBox } from "../views/nodes/ColorBox";
 import { DocuLinkBox } from "../views/nodes/DocuLinkBox";
 import { InkingStroke } from "../views/InkingStroke";
 import { InkField } from "../../new_fields/InkField";
-var requestImageSize = require('../util/request-image-size');
-var path = require('path');
+const requestImageSize = require('../util/request-image-size');
+const path = require('path');
 
 export interface DocumentOptions {
     x?: number;
@@ -239,16 +239,16 @@ export namespace Docs {
             ProxyField.initPlugin();
             ComputedField.initPlugin();
             // non-guid string ids for each document prototype
-            let prototypeIds = Object.values(DocumentType).filter(type => type !== DocumentType.NONE).map(type => type + suffix);
+            const prototypeIds = Object.values(DocumentType).filter(type => type !== DocumentType.NONE).map(type => type + suffix);
             // fetch the actual prototype documents from the server
-            let actualProtos = await DocServer.GetRefFields(prototypeIds);
+            const actualProtos = await DocServer.GetRefFields(prototypeIds);
 
             // update this object to include any default values: DocumentOptions for all prototypes
             prototypeIds.map(id => {
-                let existing = actualProtos[id] as Doc;
-                let type = id.replace(suffix, "") as DocumentType;
+                const existing = actualProtos[id] as Doc;
+                const type = id.replace(suffix, "") as DocumentType;
                 // get or create prototype of the specified type...
-                let target = existing || buildPrototype(type, id);
+                const target = existing || buildPrototype(type, id);
                 // ...and set it if not undefined (can be undefined only if TemplateMap does not contain
                 // an entry dedicated to the given DocumentType)
                 target && PrototypeMap.set(type, target);
@@ -287,17 +287,17 @@ export namespace Docs {
          */
         function buildPrototype(type: DocumentType, prototypeId: string): Opt<Doc> {
             // load template from type
-            let template = TemplateMap.get(type);
+            const template = TemplateMap.get(type);
             if (!template) {
                 return undefined;
             }
-            let layout = template.layout;
+            const layout = template.layout;
             // create title
-            let upper = suffix.toUpperCase();
-            let title = prototypeId.toUpperCase().replace(upper, `_${upper}`);
+            const upper = suffix.toUpperCase();
+            const title = prototypeId.toUpperCase().replace(upper, `_${upper}`);
             // synthesize the default options, the type and title from computed values and
             // whatever options pertain to this specific prototype
-            let options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) };
+            const options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) };
             options.layout = layout.view.LayoutString(layout.dataField);
             return Doc.assign(new Doc(prototypeId, true), { ...options });
         }
@@ -343,8 +343,8 @@ export namespace Docs {
 
             protoProps.isPrototype = true;
 
-            let dataDoc = MakeDataDelegate(proto, protoProps, data);
-            let viewDoc = Doc.MakeDelegate(dataDoc, delegId);
+            const dataDoc = MakeDataDelegate(proto, protoProps, data);
+            const viewDoc = Doc.MakeDelegate(dataDoc, delegId);
 
             AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: viewDoc }, { doc: d }, "audio link", "link to audio: " + d.title));
 
@@ -370,16 +370,16 @@ export namespace Docs {
         }
 
         export function ImageDocument(url: string, options: DocumentOptions = {}) {
-            let imgField = new ImageField(new URL(url));
-            let inst = InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: path.basename(url), ...options });
+            const imgField = new ImageField(new URL(url));
+            const inst = InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: path.basename(url), ...options });
             let target = imgField.url.href;
             if (new RegExp(window.location.origin).test(target)) {
-                let extension = path.extname(target);
+                const extension = path.extname(target);
                 target = `${target.substring(0, target.length - extension.length)}_o${extension}`;
             }
             requestImageSize(target)
                 .then((size: any) => {
-                    let aspect = size.height / size.width;
+                    const aspect = size.height / size.width;
                     if (!inst.nativeWidth) {
                         inst.nativeWidth = size.width;
                     }
@@ -423,7 +423,7 @@ export namespace Docs {
         }
 
         export function InkDocument(color: string, tool: number, strokeWidth: number, points: { x: number, y: number }[], options: DocumentOptions = {}) {
-            let doc = InstanceFromProto(Prototypes.get(DocumentType.INK), new InkField(points), options);
+            const doc = InstanceFromProto(Prototypes.get(DocumentType.INK), new InkField(points), options);
             doc.color = color;
             doc.strokeWidth = strokeWidth;
             doc.tool = tool;
@@ -439,12 +439,12 @@ export namespace Docs {
         }
 
         export async function DBDocument(url: string, options: DocumentOptions = {}, columnOptions: DocumentOptions = {}) {
-            let schemaName = options.title ? options.title : "-no schema-";
-            let ctlog = await Gateway.Instance.GetSchema(url, schemaName);
+            const schemaName = options.title ? options.title : "-no schema-";
+            const ctlog = await Gateway.Instance.GetSchema(url, schemaName);
             if (ctlog && ctlog.schemas) {
-                let schema = ctlog.schemas[0];
-                let schemaDoc = Docs.Create.TreeDocument([], { ...options, nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: schema.displayName! });
-                let schemaDocuments = Cast(schemaDoc.data, listSpec(Doc), []);
+                const schema = ctlog.schemas[0];
+                const schemaDoc = Docs.Create.TreeDocument([], { ...options, nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: schema.displayName! });
+                const schemaDocuments = Cast(schemaDoc.data, listSpec(Doc), []);
                 if (!schemaDocuments) {
                     return;
                 }
@@ -455,8 +455,8 @@ export namespace Docs {
                         if (field instanceof Doc) {
                             docs.push(field);
                         } else {
-                            var atmod = new ColumnAttributeModel(attr);
-                            let histoOp = new HistogramOperation(schema.displayName!,
+                            const atmod = new ColumnAttributeModel(attr);
+                            const histoOp = new HistogramOperation(schema.displayName!,
                                 new AttributeTransformationModel(atmod, AggregateFunction.None),
                                 new AttributeTransformationModel(atmod, AggregateFunction.Count),
                                 new AttributeTransformationModel(atmod, AggregateFunction.Count));
@@ -523,7 +523,7 @@ export namespace Docs {
         }
 
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
-            let inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+            const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
             Doc.GetProto(inst).data = new List<Doc>(documents);
             return inst;
         }
@@ -538,7 +538,7 @@ export namespace Docs {
         };
 
         export function StandardCollectionDockingDocument(configs: Array<DocConfig>, options: DocumentOptions, id?: string, type: string = "row") {
-            let layoutConfig = {
+            const layoutConfig = {
                 content: [
                     {
                         type: type,
@@ -603,7 +603,8 @@ export namespace Docs {
          * might involve arbitrary recursion (since toField might itself call convertObject)
          */
         const convertObject = (object: any, title?: string): Doc => {
-            let target = new Doc(), result: Opt<Field>;
+            const target = new Doc();
+            let result: Opt<Field>;
             Object.keys(object).map(key => (result = toField(object[key], key)) && (target[key] = result));
             title && !target.title && (target.title = title);
             return target;
@@ -617,7 +618,8 @@ export namespace Docs {
          * might involve arbitrary recursion (since toField might itself call convertList)
          */
         const convertList = (list: Array<any>): List<Field> => {
-            let target = new List(), result: Opt<Field>;
+            const target = new List();
+            let result: Opt<Field>;
             list.map(item => (result = toField(item)) && target.push(result));
             return target;
         };
@@ -658,11 +660,11 @@ export namespace Docs {
             }
             if (type.indexOf("html") !== -1) {
                 if (path.includes(window.location.hostname)) {
-                    let s = path.split('/');
-                    let id = s[s.length - 1];
+                    const s = path.split('/');
+                    const id = s[s.length - 1];
                     return DocServer.GetRefField(id).then(field => {
                         if (field instanceof Doc) {
-                            let alias = Doc.MakeAlias(field);
+                            const alias = Doc.MakeAlias(field);
                             alias.x = options.x || 0;
                             alias.y = options.y || 0;
                             alias.width = options.width || 300;
@@ -699,9 +701,9 @@ export namespace DocUtils {
                     DocListCastAsync(promoteDoc.links).then(links => {
                         links && links.map(async link => {
                             if (link) {
-                                let a1 = await Cast(link.anchor1, Doc);
+                                const a1 = await Cast(link.anchor1, Doc);
                                 if (a1 && Doc.AreProtosEqual(a1, promoteDoc)) link.anchor1 = copy;
-                                let a2 = await Cast(link.anchor2, Doc);
+                                const a2 = await Cast(link.anchor2, Doc);
                                 if (a2 && Doc.AreProtosEqual(a2, promoteDoc)) link.anchor2 = copy;
                                 LinkManager.Instance.deleteLink(link);
                                 LinkManager.Instance.addLink(link);
@@ -714,11 +716,11 @@ export namespace DocUtils {
     }
 
     export function MakeLink(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, title: string = "", description: string = "", id?: string) {
-        let sv = DocumentManager.Instance.getDocumentView(source.doc);
+        const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
         if (target.doc === CurrentUserUtils.UserDocument) return undefined;
 
-        let linkDocProto = new Doc(id, true);
+        const linkDocProto = new Doc(id, true);
         UndoManager.RunInBatch(() => {
             linkDocProto.type = DocumentType.LINK;
 
diff --git a/src/client/northstar/dash-fields/HistogramField.ts b/src/client/northstar/dash-fields/HistogramField.ts
index e6f32272e..f3365e73d 100644
--- a/src/client/northstar/dash-fields/HistogramField.ts
+++ b/src/client/northstar/dash-fields/HistogramField.ts
@@ -10,7 +10,7 @@ import { Deserializable } from "../../util/SerializationHelper";
 import { Copy, ToScriptString } from "../../../new_fields/FieldSymbols";
 
 function serialize(field: HistogramField) {
-    let obj = OmitKeys(field, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit;
+    const obj = OmitKeys(field, ['Links', 'BrushLinks', 'Result', 'BrushColors', 'FilterModels', 'FilterOperand']).omit;
     return obj;
 }
 
@@ -19,7 +19,7 @@ function deserialize(jp: any) {
     let Y: AttributeTransformationModel | undefined;
     let V: AttributeTransformationModel | undefined;
 
-    let schema = CurrentUserUtils.GetNorthstarSchema(jp.SchemaName);
+    const schema = CurrentUserUtils.GetNorthstarSchema(jp.SchemaName);
     if (schema) {
         CurrentUserUtils.GetAllNorthstarColumnAttributes(schema).map(attr => {
             if (attr.displayName === jp.X.AttributeModel.Attribute.DisplayName) {
@@ -52,8 +52,8 @@ export class HistogramField extends ObjectField {
     }
 
     [Copy]() {
-        let y = this.HistoOp;
-        let z = this.HistoOp.Copy;
+        // const y = this.HistoOp;
+        // const z = this.HistoOp.Copy;
         return new HistogramField(HistogramOperation.Duplicate(this.HistoOp));
     }
 
diff --git a/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts b/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts
index c579c8e5f..7bc097e1d 100644
--- a/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts
+++ b/src/client/northstar/model/binRanges/QuantitativeVisualBinRange.ts
@@ -37,7 +37,7 @@ export class QuantitativeVisualBinRange extends VisualBinRange {
     }
 
     public GetBins(): number[] {
-        let bins = new Array<number>();
+        const bins = new Array<number>();
 
         for (let v: number = this.DataBinRange.minValue!; v < this.DataBinRange.maxValue!; v += this.DataBinRange.step!) {
             bins.push(v);
@@ -46,8 +46,8 @@ export class QuantitativeVisualBinRange extends VisualBinRange {
     }
 
     public static Initialize(dataMinValue: number, dataMaxValue: number, targetBinNumber: number, isIntegerRange: boolean): QuantitativeVisualBinRange {
-        let extent = QuantitativeVisualBinRange.getExtent(dataMinValue, dataMaxValue, targetBinNumber, isIntegerRange);
-        let dataBinRange = new QuantitativeBinRange();
+        const extent = QuantitativeVisualBinRange.getExtent(dataMinValue, dataMaxValue, targetBinNumber, isIntegerRange);
+        const dataBinRange = new QuantitativeBinRange();
         dataBinRange.minValue = extent[0];
         dataBinRange.maxValue = extent[1];
         dataBinRange.step = extent[2];
@@ -60,10 +60,10 @@ export class QuantitativeVisualBinRange extends VisualBinRange {
             // dataMin -= 0.1;
             dataMax += 0.1;
         }
-        let span = dataMax - dataMin;
+        const span = dataMax - dataMin;
 
         let step = Math.pow(10, Math.floor(Math.log10(span / m)));
-        let err = m / span * step;
+        const err = m / span * step;
 
         if (err <= .15) {
             step *= 10;
@@ -78,9 +78,9 @@ export class QuantitativeVisualBinRange extends VisualBinRange {
         if (isIntegerRange) {
             step = Math.ceil(step);
         }
-        let ret: number[] = new Array<number>(3);
-        let minDivStep = Math.floor(dataMin / step);
-        let maxDivStep = Math.floor(dataMax / step);
+        const ret: number[] = new Array<number>(3);
+        const minDivStep = Math.floor(dataMin / step);
+        const maxDivStep = Math.floor(dataMax / step);
         ret[0] = minDivStep * step; // Math.floor(Math.Round(dataMin, 8)/step)*step;
         ret[1] = maxDivStep * step + step; // Math.floor(Math.Round(dataMax, 8)/step)*step + step;
         ret[2] = step;
diff --git a/src/client/northstar/operations/BaseOperation.ts b/src/client/northstar/operations/BaseOperation.ts
index 0d1361ebf..013f2244e 100644
--- a/src/client/northstar/operations/BaseOperation.ts
+++ b/src/client/northstar/operations/BaseOperation.ts
@@ -44,12 +44,12 @@ export abstract class BaseOperation {
                 }
             }
 
-            let operationParameters = this.CreateOperationParameters();
+            const operationParameters = this.CreateOperationParameters();
             if (this.Result) {
                 this.Result.progress = 0;
             } // bcz: used to set Result to undefined, but that causes the display to blink
             this.Error = "";
-            let salt = Math.random().toString();
+            const salt = Math.random().toString();
             this.RequestSalt = salt;
 
             if (!operationParameters) {
@@ -59,27 +59,27 @@ export abstract class BaseOperation {
 
             this.ComputationStarted = true;
             //let start = performance.now();
-            let promise = Gateway.Instance.StartOperation(operationParameters.toJSON());
+            const promise = Gateway.Instance.StartOperation(operationParameters.toJSON());
             promise.catch(err => {
                 action(() => {
                     this.Error = err;
                     console.error(err);
                 });
             });
-            let operationReference = await promise;
+            const operationReference = await promise;
 
 
             if (operationReference) {
                 this.OperationReference = operationReference;
 
-                let resultParameters = new ResultParameters();
+                const resultParameters = new ResultParameters();
                 resultParameters.operationReference = operationReference;
 
-                let pollPromise = new PollPromise(salt, operationReference);
+                const pollPromise = new PollPromise(salt, operationReference);
                 BaseOperation._currentOperations.set(this.Id, pollPromise);
 
                 pollPromise.Start(async () => {
-                    let result = await Gateway.Instance.GetResult(resultParameters.toJSON());
+                    const result = await Gateway.Instance.GetResult(resultParameters.toJSON());
                     if (result instanceof ErrorResult) {
                         throw new Error((result).message);
                     }
diff --git a/src/client/northstar/utils/MathUtil.ts b/src/client/northstar/utils/MathUtil.ts
index 4b44f40c3..5def5e704 100644
--- a/src/client/northstar/utils/MathUtil.ts
+++ b/src/client/northstar/utils/MathUtil.ts
@@ -92,37 +92,37 @@ export class MathUtil {
 
     public static DistToLineSegment(v: PIXIPoint, w: PIXIPoint, p: PIXIPoint) {
         // Return minimum distance between line segment vw and point p
-        var l2 = MathUtil.DistSquared(v, w);  // i.e. |w-v|^2 -  avoid a sqrt
+        const l2 = MathUtil.DistSquared(v, w);  // i.e. |w-v|^2 -  avoid a sqrt
         if (l2 === 0.0) return MathUtil.Dist(p, v);   // v === w case
         // Consider the line extending the segment, parameterized as v + t (w - v).
         // We find projection of point p onto the line. 
         // It falls where t = [(p-v) . (w-v)] / |w-v|^2
         // We clamp t from [0,1] to handle points outside the segment vw.
-        var dot = MathUtil.Dot(
+        const dot = MathUtil.Dot(
             MathUtil.SubtractPoint(p, v),
             MathUtil.SubtractPoint(w, v)) / l2;
-        var t = Math.max(0, Math.min(1, dot));
+        const t = Math.max(0, Math.min(1, dot));
         // Projection falls on the segment
-        var projection = MathUtil.AddPoint(v,
+        const projection = MathUtil.AddPoint(v,
             MathUtil.MultiplyConstant(
                 MathUtil.SubtractPoint(w, v), t));
         return MathUtil.Dist(p, projection);
     }
 
     public static LineSegmentIntersection(ps1: PIXIPoint, pe1: PIXIPoint, ps2: PIXIPoint, pe2: PIXIPoint): PIXIPoint | undefined {
-        var a1 = pe1.y - ps1.y;
-        var b1 = ps1.x - pe1.x;
+        const a1 = pe1.y - ps1.y;
+        const b1 = ps1.x - pe1.x;
 
-        var a2 = pe2.y - ps2.y;
-        var b2 = ps2.x - pe2.x;
+        const a2 = pe2.y - ps2.y;
+        const b2 = ps2.x - pe2.x;
 
-        var delta = a1 * b2 - a2 * b1;
+        const delta = a1 * b2 - a2 * b1;
         if (delta === 0) {
             return undefined;
         }
-        var c2 = a2 * ps2.x + b2 * ps2.y;
-        var c1 = a1 * ps1.x + b1 * ps1.y;
-        var invdelta = 1 / delta;
+        const c2 = a2 * ps2.x + b2 * ps2.y;
+        const c1 = a1 * ps1.x + b1 * ps1.y;
+        const invdelta = 1 / delta;
         return new PIXIPoint((b2 * c1 - b1 * c2) * invdelta, (a1 * c2 - a2 * c1) * invdelta);
     }
 
@@ -144,13 +144,13 @@ export class MathUtil {
     }
 
     public static LinePIXIRectangleIntersection(lineFrom: PIXIPoint, lineTo: PIXIPoint, rect: PIXIRectangle): Array<PIXIPoint> {
-        var r1 = new PIXIPoint(rect.left, rect.top);
-        var r2 = new PIXIPoint(rect.right, rect.top);
-        var r3 = new PIXIPoint(rect.right, rect.bottom);
-        var r4 = new PIXIPoint(rect.left, rect.bottom);
-        var ret = new Array<PIXIPoint>();
-        var dist = this.Dist(lineFrom, lineTo);
-        var inter = this.LineSegmentIntersection(lineFrom, lineTo, r1, r2);
+        const r1 = new PIXIPoint(rect.left, rect.top);
+        const r2 = new PIXIPoint(rect.right, rect.top);
+        const r3 = new PIXIPoint(rect.right, rect.bottom);
+        const r4 = new PIXIPoint(rect.left, rect.bottom);
+        const ret = new Array<PIXIPoint>();
+        const dist = this.Dist(lineFrom, lineTo);
+        let inter = this.LineSegmentIntersection(lineFrom, lineTo, r1, r2);
         if (inter && this.PointInPIXIRectangle(inter, rect) &&
             this.Dist(inter, lineFrom) < dist && this.Dist(inter, lineTo) < dist) {
             ret.push(inter);
@@ -190,7 +190,7 @@ export class MathUtil {
     }
 
     public static Normalize(p1: PIXIPoint) {
-        var d = this.Length(p1);
+        const d = this.Length(p1);
         return new PIXIPoint(p1.x / d, p1.y / d);
     }
 
@@ -236,8 +236,8 @@ export class MathUtil {
     }
 
     public static Combinations<T>(chars: T[]) {
-        let result = new Array<T>();
-        let f = (prefix: any, chars: any) => {
+        const result = new Array<T>();
+        const f = (prefix: any, chars: any) => {
             for (let i = 0; i < chars.length; i++) {
                 result.push(prefix.concat(chars[i]));
                 f(prefix.concat(chars[i]), chars.slice(i + 1));
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 6bbd3d0ed..3d8f2d234 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -11,7 +11,6 @@ import { Cast, CastCtor } from "../../new_fields/Types";
 import { listSpec } from "../../new_fields/Schema";
 import { AudioField, ImageField } from "../../new_fields/URLField";
 import { HistogramField } from "../northstar/dash-fields/HistogramField";
-import { MainView } from "../views/MainView";
 import { Utils } from "../../Utils";
 import { RichTextField } from "../../new_fields/RichTextField";
 import { DictationOverlay } from "../views/DictationOverlay";
@@ -48,7 +47,7 @@ export namespace DictationManager {
 
         export const Infringed = "unable to process: dictation manager still involved in previous session";
         const browser = (() => {
-            let identifier = navigator.userAgent.toLowerCase();
+            const identifier = navigator.userAgent.toLowerCase();
             if (identifier.indexOf("safari") >= 0) {
                 return "Safari";
             }
@@ -90,7 +89,7 @@ export namespace DictationManager {
         export const listen = async (options?: Partial<ListeningOptions>) => {
             let results: string | undefined;
 
-            let overlay = options !== undefined && options.useOverlay;
+            const overlay = options !== undefined && options.useOverlay;
             if (overlay) {
                 DictationOverlay.Instance.dictationOverlayVisible = true;
                 DictationOverlay.Instance.isListening = { interim: false };
@@ -102,7 +101,7 @@ export namespace DictationManager {
                     Utils.CopyText(results);
                     if (overlay) {
                         DictationOverlay.Instance.isListening = false;
-                        let execute = options && options.tryExecute;
+                        const execute = options && options.tryExecute;
                         DictationOverlay.Instance.dictatedPhrase = execute ? results.toLowerCase() : results;
                         DictationOverlay.Instance.dictationSuccess = execute ? await DictationManager.Commands.execute(results) : true;
                     }
@@ -131,12 +130,12 @@ export namespace DictationManager {
             }
             isListening = true;
 
-            let handler = options ? options.interimHandler : undefined;
-            let continuous = options ? options.continuous : undefined;
-            let indefinite = continuous && continuous.indefinite;
-            let language = options ? options.language : undefined;
-            let intra = options && options.delimiters ? options.delimiters.intra : undefined;
-            let inter = options && options.delimiters ? options.delimiters.inter : undefined;
+            const handler = options ? options.interimHandler : undefined;
+            const continuous = options ? options.continuous : undefined;
+            const indefinite = continuous && continuous.indefinite;
+            const language = options ? options.language : undefined;
+            const intra = options && options.delimiters ? options.delimiters.intra : undefined;
+            const inter = options && options.delimiters ? options.delimiters.inter : undefined;
 
             recognizer.onstart = () => console.log("initiating speech recognition session...");
             recognizer.interimResults = handler !== undefined;
@@ -177,7 +176,7 @@ export namespace DictationManager {
                     recognizer.start();
                 };
 
-                let complete = () => {
+                const complete = () => {
                     if (indefinite) {
                         current && sessionResults.push(current);
                         sessionResults.length && resolve(sessionResults.join(inter || interSession));
@@ -213,8 +212,8 @@ export namespace DictationManager {
         };
 
         const synthesize = (e: SpeechRecognitionEvent, delimiter?: string) => {
-            let results = e.results;
-            let transcripts: string[] = [];
+            const results = e.results;
+            const transcripts: string[] = [];
             for (let i = 0; i < results.length; i++) {
                 transcripts.push(results.item(i).item(0).transcript.trim());
             }
@@ -238,18 +237,18 @@ export namespace DictationManager {
 
         export const execute = async (phrase: string) => {
             return UndoManager.RunInBatch(async () => {
-                let targets = SelectionManager.SelectedDocuments();
+                const targets = SelectionManager.SelectedDocuments();
                 if (!targets || !targets.length) {
                     return;
                 }
 
                 phrase = phrase.toLowerCase();
-                let entry = Independent.get(phrase);
+                const entry = Independent.get(phrase);
 
                 if (entry) {
                     let success = false;
-                    let restrictTo = entry.restrictTo;
-                    for (let target of targets) {
+                    const restrictTo = entry.restrictTo;
+                    for (const target of targets) {
                         if (!restrictTo || validate(target, restrictTo)) {
                             await entry.action(target);
                             success = true;
@@ -258,14 +257,14 @@ export namespace DictationManager {
                     return success;
                 }
 
-                for (let entry of Dependent) {
-                    let regex = entry.expression;
-                    let matches = regex.exec(phrase);
+                for (const entry of Dependent) {
+                    const regex = entry.expression;
+                    const matches = regex.exec(phrase);
                     regex.lastIndex = 0;
                     if (matches !== null) {
                         let success = false;
-                        let restrictTo = entry.restrictTo;
-                        for (let target of targets) {
+                        const restrictTo = entry.restrictTo;
+                        for (const target of targets) {
                             if (!restrictTo || validate(target, restrictTo)) {
                                 await entry.action(target, matches);
                                 success = true;
@@ -289,7 +288,7 @@ export namespace DictationManager {
         ]);
 
         const tryCast = (view: DocumentView, type: DocumentType) => {
-            let ctor = ConstructorMap.get(type);
+            const ctor = ConstructorMap.get(type);
             if (!ctor) {
                 return false;
             }
@@ -297,7 +296,7 @@ export namespace DictationManager {
         };
 
         const validate = (target: DocumentView, types: DocumentType[]) => {
-            for (let type of types) {
+            for (const type of types) {
                 if (tryCast(target, type)) {
                     return true;
                 }
@@ -306,11 +305,11 @@ export namespace DictationManager {
         };
 
         const interpretNumber = (number: string) => {
-            let initial = parseInt(number);
+            const initial = parseInt(number);
             if (!isNaN(initial)) {
                 return initial;
             }
-            let converted = interpreter.wordsToNumbers(number, { fuzzy: true });
+            const converted = interpreter.wordsToNumbers(number, { fuzzy: true });
             if (converted === null) {
                 return NaN;
             }
@@ -326,20 +325,20 @@ export namespace DictationManager {
 
             ["open fields", {
                 action: (target: DocumentView) => {
-                    let kvp = Docs.Create.KVPDocument(target.props.Document, { width: 300, height: 300 });
+                    const kvp = Docs.Create.KVPDocument(target.props.Document, { width: 300, height: 300 });
                     target.props.addDocTab(kvp, target.props.DataDoc, "onRight");
                 }
             }],
 
             ["new outline", {
                 action: (target: DocumentView) => {
-                    let newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" });
+                    const newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" });
                     newBox.autoHeight = true;
-                    let proto = newBox.proto!;
-                    let prompt = "Press alt + r to start dictating here...";
-                    let head = 3;
-                    let anchor = head + prompt.length;
-                    let proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`;
+                    const proto = newBox.proto!;
+                    const prompt = "Press alt + r to start dictating here...";
+                    const head = 3;
+                    const anchor = head + prompt.length;
+                    const proseMirrorState = `{"doc":{"type":"doc","content":[{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"type":"text","text":"${prompt}"}]}]}]}]},"selection":{"type":"text","anchor":${anchor},"head":${head}}}`;
                     proto.data = new RichTextField(proseMirrorState);
                     proto.backgroundColor = "#eeffff";
                     target.props.addDocTab(newBox, proto, "onRight");
@@ -353,10 +352,10 @@ export namespace DictationManager {
             {
                 expression: /create (\w+) documents of type (image|nested collection)/g,
                 action: (target: DocumentView, matches: RegExpExecArray) => {
-                    let count = interpretNumber(matches[1]);
-                    let what = matches[2];
-                    let dataDoc = Doc.GetProto(target.props.Document);
-                    let fieldKey = "data";
+                    const count = interpretNumber(matches[1]);
+                    const what = matches[2];
+                    const dataDoc = Doc.GetProto(target.props.Document);
+                    const fieldKey = "data";
                     if (isNaN(count)) {
                         return;
                     }
@@ -379,7 +378,7 @@ export namespace DictationManager {
             {
                 expression: /view as (freeform|stacking|masonry|schema|tree)/g,
                 action: (target: DocumentView, matches: RegExpExecArray) => {
-                    let mode = CollectionViewType.valueOf(matches[1]);
+                    const mode = CollectionViewType.valueOf(matches[1]);
                     mode && (target.props.Document.viewType = mode);
                 },
                 restrictTo: [DocumentType.COL]
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 346e88f40..d491cd1b1 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -33,7 +33,7 @@ export class DocumentManager {
 
     //gets all views
     public getDocumentViewsById(id: string) {
-        let toReturn: DocumentView[] = [];
+        const toReturn: DocumentView[] = [];
         DocumentManager.Instance.DocumentViews.map(view => {
             if (view.props.Document[Id] === id) {
                 toReturn.push(view);
@@ -41,7 +41,7 @@ export class DocumentManager {
         });
         if (toReturn.length === 0) {
             DocumentManager.Instance.DocumentViews.map(view => {
-                let doc = view.props.Document.proto;
+                const doc = view.props.Document.proto;
                 if (doc && doc[Id] && doc[Id] === id) {
                     toReturn.push(view);
                 }
@@ -57,9 +57,9 @@ export class DocumentManager {
     public getDocumentViewById(id: string, preferredCollection?: CollectionView): DocumentView | undefined {
 
         let toReturn: DocumentView | undefined;
-        let passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
+        const passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
 
-        for (let pass of passes) {
+        for (const pass of passes) {
             DocumentManager.Instance.DocumentViews.map(view => {
                 if (view.props.Document[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) {
                     toReturn = view;
@@ -68,7 +68,7 @@ export class DocumentManager {
             });
             if (!toReturn) {
                 DocumentManager.Instance.DocumentViews.map(view => {
-                    let doc = view.props.Document.proto;
+                    const doc = view.props.Document.proto;
                     if (doc && doc[Id] === id && (!pass || view.props.ContainingCollectionView === preferredCollection)) {
                         toReturn = view;
                     }
@@ -90,7 +90,7 @@ export class DocumentManager {
         return views.length ? views[0] : undefined;
     }
     public getDocumentViews(toFind: Doc): DocumentView[] {
-        let toReturn: DocumentView[] = [];
+        const toReturn: DocumentView[] = [];
 
         DocumentManager.Instance.DocumentViews.map(view =>
             Doc.AreProtosEqual(view.props.Document, toFind) && toReturn.push(view));
@@ -100,17 +100,17 @@ export class DocumentManager {
 
     @computed
     public get LinkedDocumentViews() {
-        let pairs = DocumentManager.Instance.DocumentViews.filter(dv =>
+        const pairs = DocumentManager.Instance.DocumentViews.filter(dv =>
             (dv.isSelected() || Doc.IsBrushed(dv.props.Document)) // draw links from DocumentViews that are selected or brushed OR
             || DocumentManager.Instance.DocumentViews.some(dv2 => {                                                  // Documentviews which
-                let rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors 
-                let init = (dv2.isSelected() || Doc.IsBrushed(dv2.props.Document)) && dv2.Document.type !== DocumentType.AUDIO;  // on a view that is selected or brushed
+                const rest = DocListCast(dv2.props.Document.links).some(l => Doc.AreProtosEqual(l, dv.props.Document));// are link doc anchors 
+                const init = (dv2.isSelected() || Doc.IsBrushed(dv2.props.Document)) && dv2.Document.type !== DocumentType.AUDIO;  // on a view that is selected or brushed
                 return init && rest;
             })
         ).reduce((pairs, dv) => {
-            let linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document);
+            const linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document);
             pairs.push(...linksList.reduce((pairs, link) => {
-                let linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document);
+                const linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document);
                 linkToDoc && DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => {
                     if (dv.props.Document.type !== DocumentType.LINK || dv.props.layoutKey !== docView1.props.layoutKey) {
                         pairs.push({ a: dv, b: docView1, l: link });
@@ -125,7 +125,7 @@ export class DocumentManager {
     }
 
     public jumpToDocument = async (targetDoc: Doc, willZoom: boolean, dockFunc?: (doc: Doc) => void, docContext?: Doc, linkId?: string, closeContextIfNotFound: boolean = false): Promise<void> => {
-        let highlight = () => {
+        const highlight = () => {
             const finalDocView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
             finalDocView && (finalDocView.Document.scrollToLinkID = linkId);
             finalDocView && Doc.linkFollowHighlight(finalDocView.props.Document);
@@ -199,12 +199,12 @@ export class DocumentManager {
 
     @action
     zoomIntoScale = (docDelegate: Doc, scale: number) => {
-        let docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate));
+        const docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate));
         docView && docView.props.zoomToScale(scale);
     }
 
     getScaleOfDocView = (docDelegate: Doc) => {
-        let doc = Doc.GetProto(docDelegate);
+        const doc = Doc.GetProto(docDelegate);
 
         const docView = DocumentManager.Instance.getDocumentView(doc);
         if (docView) {
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index bbc29585c..b681387d1 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,7 +1,6 @@
 import { action, runInAction } from "mobx";
 import { Doc, Field } from "../../new_fields/Doc";
-import { Cast, StrCast, ScriptCast } from "../../new_fields/Types";
-import { URLField } from "../../new_fields/URLField";
+import { Cast, ScriptCast } from "../../new_fields/Types";
 import { emptyFunction } from "../../Utils";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import * as globalCssVariables from "../views/globalCssVariables.scss";
@@ -27,14 +26,14 @@ export function SetupDrag(
     dontHideOnDrop?: boolean,
     dragStarted?: () => void
 ) {
-    let onRowMove = async (e: PointerEvent) => {
+    const onRowMove = async (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
 
         document.removeEventListener("pointermove", onRowMove);
         document.removeEventListener('pointerup', onRowUp);
-        let doc = await docFunc();
-        var dragData = new DragManager.DocumentDragData([doc]);
+        const doc = await docFunc();
+        const dragData = new DragManager.DocumentDragData([doc]);
         dragData.dropAction = dropAction;
         dragData.moveDocument = moveFunc;
         dragData.options = options;
@@ -42,11 +41,11 @@ export function SetupDrag(
         DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
         dragStarted && dragStarted();
     };
-    let onRowUp = (): void => {
+    const onRowUp = (): void => {
         document.removeEventListener("pointermove", onRowMove);
         document.removeEventListener('pointerup', onRowUp);
     };
-    let onItemDown = async (e: React.PointerEvent) => {
+    const onItemDown = async (e: React.PointerEvent) => {
         if (e.button === 0) {
             e.stopPropagation();
             if (e.shiftKey && CollectionDockingView.Instance) {
@@ -74,11 +73,11 @@ function moveLinkedDocument(doc: Doc, targetCollection: Doc, addDocument: (doc:
 }
 
 export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: number, linkDoc: Doc, sourceDoc: Doc) {
-    let draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc);
+    const draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc);
     if (draggeddoc) {
-        let moddrag = await Cast(draggeddoc.annotationOn, Doc);
-        let dragdocs = moddrag ? [moddrag] : [draggeddoc];
-        let dragData = new DragManager.DocumentDragData(dragdocs);
+        const moddrag = await Cast(draggeddoc.annotationOn, Doc);
+        const dragdocs = moddrag ? [moddrag] : [draggeddoc];
+        const dragData = new DragManager.DocumentDragData(dragdocs);
         dragData.moveDocument = moveLinkedDocument;
         DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
             handlers: {
@@ -90,26 +89,26 @@ export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: num
 }
 
 export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc, singleLink?: Doc) {
-    let srcTarg = sourceDoc.proto;
+    const srcTarg = sourceDoc.proto;
     let draggedDocs: Doc[] = [];
 
     if (srcTarg) {
-        let linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg);
+        const linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg);
         if (linkDocs) {
             draggedDocs = linkDocs.map(link => {
-                let opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc);
+                const opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc);
                 if (opp) return opp;
             }) as Doc[];
         }
     }
     if (draggedDocs.length) {
-        let moddrag: Doc[] = [];
+        const moddrag: Doc[] = [];
         for (const draggedDoc of draggedDocs) {
-            let doc = await Cast(draggedDoc.annotationOn, Doc);
+            const doc = await Cast(draggedDoc.annotationOn, Doc);
             if (doc) moddrag.push(doc);
         }
-        let dragdocs = moddrag.length ? moddrag : draggedDocs;
-        let dragData = new DragManager.DocumentDragData(dragdocs);
+        const dragdocs = moddrag.length ? moddrag : draggedDocs;
+        const dragData = new DragManager.DocumentDragData(dragdocs);
         dragData.moveDocument = moveLinkedDocument;
         DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
             handlers: {
@@ -254,11 +253,11 @@ export namespace DragManager {
     }
 
     export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
-        let dragData = new DragManager.DocumentDragData([]);
+        const dragData = new DragManager.DocumentDragData([]);
         runInAction(() => StartDragFunctions.map(func => func()));
         StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
             (dropData: { [id: string]: any }) => {
-                let bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+                const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
                 bd.onClick = ScriptField.MakeScript(script);
                 params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
                 initialize && initialize(bd);
@@ -273,11 +272,11 @@ export namespace DragManager {
         runInAction(() => StartDragFunctions.map(func => func()));
         StartDrag(eles, dragData, downX, downY, options,
             (dropData: { [id: string]: any }) => {
-                let droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => {
-                    let dvs = DocumentManager.Instance.getDocumentViews(d);
+                const droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => {
+                    const dvs = DocumentManager.Instance.getDocumentViews(d);
                     if (dvs.length) {
-                        let containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
-                        let inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView);
+                        const containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
+                        const inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView);
                         if (inContext.length) {
                             inContext.forEach(dv => droppedDocs.push(dv.props.Document));
                         } else {
@@ -336,26 +335,26 @@ export namespace DragManager {
             DragManager.Root().appendChild(dragDiv);
         }
         SelectionManager.SetIsDragging(true);
-        let scaleXs: number[] = [];
-        let scaleYs: number[] = [];
-        let xs: number[] = [];
-        let ys: number[] = [];
+        const scaleXs: number[] = [];
+        const scaleYs: number[] = [];
+        const xs: number[] = [];
+        const ys: number[] = [];
 
         const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments :
             dragData instanceof AnnotationDragData ? [dragData.dragDocument] : [];
-        let dragElements = eles.map(ele => {
+        const dragElements = eles.map(ele => {
             const w = ele.offsetWidth,
                 h = ele.offsetHeight;
             const rect = ele.getBoundingClientRect();
             const scaleX = rect.width / w,
                 scaleY = rect.height / h;
-            let x = rect.left,
+            const x = rect.left,
                 y = rect.top;
             xs.push(x);
             ys.push(y);
             scaleXs.push(scaleX);
             scaleYs.push(scaleY);
-            let dragElement = ele.cloneNode(true) as HTMLElement;
+            const dragElement = ele.cloneNode(true) as HTMLElement;
             dragElement.style.opacity = "0.7";
             dragElement.style.borderRadius = getComputedStyle(ele).borderRadius;
             dragElement.style.position = "absolute";
@@ -372,25 +371,25 @@ export namespace DragManager {
             dragElement.style.height = `${rect.height / scaleY}px`;
 
             if (docs.length) {
-                var pdfBox = dragElement.getElementsByTagName("canvas");
-                var pdfBoxSrc = ele.getElementsByTagName("canvas");
+                const pdfBox = dragElement.getElementsByTagName("canvas");
+                const pdfBoxSrc = ele.getElementsByTagName("canvas");
                 Array.from(pdfBox).map((pb, i) => pb.getContext('2d')!.drawImage(pdfBoxSrc[i], 0, 0));
-                var pdfView = dragElement.getElementsByClassName("pdfViewer-viewer");
-                var pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer");
-                let tops = Array.from(pdfViewSrc).map(p => p.scrollTop);
-                let oldopacity = dragElement.style.opacity;
+                const pdfView = dragElement.getElementsByClassName("pdfViewer-viewer");
+                const pdfViewSrc = ele.getElementsByClassName("pdfViewer-viewer");
+                const tops = Array.from(pdfViewSrc).map(p => p.scrollTop);
+                const oldopacity = dragElement.style.opacity;
                 dragElement.style.opacity = "0";
                 setTimeout(() => {
                     dragElement.style.opacity = oldopacity;
                     Array.from(pdfView).map((v, i) => v.scrollTo({ top: tops[i] }));
                 }, 0);
             }
-            let set = dragElement.getElementsByTagName('*');
+            const set = dragElement.getElementsByTagName('*');
             if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none";
             // tslint:disable-next-line: prefer-for-of
             for (let i = 0; i < set.length; i++) {
                 if (set[i].hasAttribute("style")) {
-                    let s = set[i];
+                    const s = set[i];
                     (s as any).style.pointerEvents = "none";
                 }
             }
@@ -429,8 +428,8 @@ export namespace DragManager {
                 }, dragData.droppedDocuments);
             }
             //TODO: Why can't we use e.movementX and e.movementY?
-            let moveX = e.pageX - lastX;
-            let moveY = e.pageY - lastY;
+            const moveX = e.pageX - lastX;
+            const moveY = e.pageY - lastY;
             lastX = e.pageX;
             lastY = e.pageY;
             dragElements.map((dragElement, i) => (dragElement.style.transform =
@@ -438,11 +437,11 @@ export namespace DragManager {
             );
         };
 
-        let hideDragShowOriginalElements = () => {
+        const hideDragShowOriginalElements = () => {
             dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
             eles.map(ele => ele.hidden = false);
         };
-        let endDrag = () => {
+        const endDrag = () => {
             document.removeEventListener("pointermove", moveHandler, true);
             document.removeEventListener("pointerup", upHandler);
             if (options) {
@@ -466,17 +465,17 @@ export namespace DragManager {
     }
 
     function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
-        let removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
+        const removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
             // let parent = dragEle.parentElement;
             // if (parent) parent.removeChild(dragEle);
-            let ret = [dragEle, dragEle.style.width, dragEle.style.height];
+            const ret = [dragEle, dragEle.style.width, dragEle.style.height];
             dragEle.style.width = "0";
             dragEle.style.height = "0";
             return ret;
         });
         const target = document.elementFromPoint(e.x, e.y);
         removed.map(r => {
-            let dragEle = r[0] as HTMLElement;
+            const dragEle = r[0] as HTMLElement;
             dragEle.style.width = r[1] as string;
             dragEle.style.height = r[2] as string;
             // let parent = r[1];
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 6b53333d7..b2c720d5d 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -9,10 +9,10 @@ import { ScriptField } from "../../new_fields/ScriptField";
 
 
 function makeTemplate(doc: Doc): boolean {
-    let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
-    let layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0];
-    let fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, "");
-    let docs = DocListCast(layoutDoc[fieldKey]);
+    const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+    const layout = StrCast(layoutDoc.layout).match(/fieldKey={"[^"]*"}/)![0];
+    const fieldKey = layout.replace('fieldKey={"', "").replace(/"}$/, "");
+    const docs = DocListCast(layoutDoc[fieldKey]);
     let any = false;
     docs.map(d => {
         if (!StrCast(d.title).startsWith("-")) {
@@ -28,7 +28,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
     data && data.draggedDocuments.map((doc, i) => {
         let dbox = doc;
         if (!doc.onDragStart && !doc.onClick && doc.viewType !== CollectionViewType.Linear) {
-            let layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+            const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
             if (layoutDoc.type === DocumentType.COL) {
                 layoutDoc.isTemplateDoc = makeTemplate(layoutDoc);
             } else {
diff --git a/src/client/util/History.ts b/src/client/util/History.ts
index 1c51236cb..545e8acb4 100644
--- a/src/client/util/History.ts
+++ b/src/client/util/History.ts
@@ -1,4 +1,4 @@
-import { Doc, Opt, Field } from "../../new_fields/Doc";
+import { Doc } from "../../new_fields/Doc";
 import { DocServer } from "../DocServer";
 import { MainView } from "../views/MainView";
 import * as qs from 'query-string';
@@ -53,7 +53,7 @@ export namespace HistoryUtil {
     }
 
     export function getState(): ParsedUrl {
-        let state = copyState(history.state);
+        const state = copyState(history.state);
         state.initializers = state.initializers || {};
         return state;
     }
@@ -160,7 +160,7 @@ export namespace HistoryUtil {
         const pathname = location.pathname.substring(1);
         const search = location.search;
         const opts = search.length ? qs.parse(search, { sort: false }) : {};
-        let pathnameSplit = pathname.split("/");
+        const pathnameSplit = pathname.split("/");
 
         const type = pathnameSplit[0];
 
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 104d9e099..e6a215b2c 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -1,7 +1,7 @@
 import "fs";
 import React = require("react");
 import { Doc, DocListCast, DocListCastAsync, Opt } from "../../../new_fields/Doc";
-import { action, observable, autorun, runInAction, computed, reaction, IReactionDisposer } from "mobx";
+import { action, observable, runInAction, computed, reaction, IReactionDisposer } from "mobx";
 import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
 import Measure, { ContentRect } from "react-measure";
 import { library } from '@fortawesome/fontawesome-svg-core';
@@ -48,7 +48,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
     constructor(props: FieldViewProps) {
         super(props);
         library.add(faTag, faPlus);
-        let doc = this.props.Document;
+        const doc = this.props.Document;
         this.editingMetadata = this.editingMetadata || false;
         this.persistent = this.persistent || false;
         !Cast(doc.data, listSpec(Doc)) && (doc.data = new List<Doc>());
@@ -78,16 +78,16 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
             this.phase = "Initializing download...";
         });
 
-        let docs: Doc[] = [];
+        const docs: Doc[] = [];
 
-        let files = e.target.files;
+        const files = e.target.files;
         if (!files || files.length === 0) return;
 
-        let directory = (files.item(0) as any).webkitRelativePath.split("/", 1)[0];
+        const directory = (files.item(0) as any).webkitRelativePath.split("/", 1)[0];
 
-        let validated: File[] = [];
+        const validated: File[] = [];
         for (let i = 0; i < files.length; i++) {
-            let file = files.item(i);
+            const file = files.item(i);
             if (file && !unsupported.includes(file.type)) {
                 const ext = path.extname(file.name).toLowerCase();
                 if (AcceptibleMedia.imageFormats.includes(ext)) {
@@ -101,8 +101,8 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
             this.completed = 0;
         });
 
-        let sizes: number[] = [];
-        let modifiedDates: number[] = [];
+        const sizes: number[] = [];
+        const modifiedDates: number[] = [];
 
         runInAction(() => this.phase = `Internal: uploading ${this.quota - this.completed} files to Dash...`);
 
@@ -136,26 +136,26 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
         }));
 
         for (let i = 0; i < docs.length; i++) {
-            let doc = docs[i];
+            const doc = docs[i];
             doc.size = sizes[i];
             doc.modified = modifiedDates[i];
             this.entries.forEach(entry => {
-                let target = entry.onDataDoc ? Doc.GetProto(doc) : doc;
+                const target = entry.onDataDoc ? Doc.GetProto(doc) : doc;
                 target[entry.key] = entry.value;
             });
         }
 
-        let doc = this.props.Document;
-        let height: number = NumCast(doc.height) || 0;
-        let offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0;
-        let options: DocumentOptions = {
+        const doc = this.props.Document;
+        const height: number = NumCast(doc.height) || 0;
+        const offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0;
+        const options: DocumentOptions = {
             title: `Import of ${directory}`,
             width: 1105,
             height: 500,
             x: NumCast(doc.x),
             y: NumCast(doc.y) + offset
         };
-        let parent = this.props.ContainingCollectionView;
+        const parent = this.props.ContainingCollectionView;
         if (parent) {
             let importContainer: Doc;
             if (docs.length < 50) {
@@ -194,18 +194,18 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
 
     @action
     preserveCentering = (rect: ContentRect) => {
-        let bounds = rect.offset!;
+        const bounds = rect.offset!;
         if (bounds.width === 0 || bounds.height === 0) {
             return;
         }
-        let offset = this.dimensions / 2;
+        const offset = this.dimensions / 2;
         this.left = bounds.width / 2 - offset;
         this.top = bounds.height / 2 - offset;
     }
 
     @action
     addMetadataEntry = async () => {
-        let entryDoc = new Doc();
+        const entryDoc = new Doc();
         entryDoc.checked = false;
         entryDoc.key = keyPlaceholder;
         entryDoc.value = valuePlaceholder;
@@ -214,7 +214,7 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
 
     @action
     remove = async (entry: ImportMetadataEntry) => {
-        let metadata = await DocListCastAsync(this.props.Document.data);
+        const metadata = await DocListCastAsync(this.props.Document.data);
         if (metadata) {
             let index = this.entries.indexOf(entry);
             if (index !== -1) {
@@ -228,18 +228,18 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
     }
 
     render() {
-        let dimensions = 50;
-        let entries = DocListCast(this.props.Document.data);
-        let isEditing = this.editingMetadata;
-        let completed = this.completed;
-        let quota = this.quota;
-        let uploading = this.uploading;
-        let showRemoveLabel = this.removeHover;
-        let persistent = this.persistent;
+        const dimensions = 50;
+        const entries = DocListCast(this.props.Document.data);
+        const isEditing = this.editingMetadata;
+        const completed = this.completed;
+        const quota = this.quota;
+        const uploading = this.uploading;
+        const showRemoveLabel = this.removeHover;
+        const persistent = this.persistent;
         let percent = `${completed / quota * 100}`;
         percent = percent.split(".")[0];
         percent = percent.startsWith("100") ? "99" : percent;
-        let marginOffset = (percent.length === 1 ? 5 : 0) - 1.6;
+        const marginOffset = (percent.length === 1 ? 5 : 0) - 1.6;
         const message = <span className={"phase"}>{this.phase}</span>;
         const centerPiece = this.phase.includes("Google Photos") ?
             <img src={"/assets/google_photos.png"} style={{
diff --git a/src/client/util/Import & Export/ImportMetadataEntry.tsx b/src/client/util/Import & Export/ImportMetadataEntry.tsx
index f5198c39b..8e1c50bea 100644
--- a/src/client/util/Import & Export/ImportMetadataEntry.tsx	
+++ b/src/client/util/Import & Export/ImportMetadataEntry.tsx	
@@ -1,11 +1,11 @@
 import React = require("react");
 import { observer } from "mobx-react";
 import { EditableView } from "../../views/EditableView";
-import { observable, action, computed } from "mobx";
+import { action, computed } from "mobx";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faPlus } from "@fortawesome/free-solid-svg-icons";
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { Opt, Doc } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
 import { StrCast, BoolCast } from "../../../new_fields/Types";
 
 interface KeyValueProps {
@@ -85,7 +85,7 @@ export default class ImportMetadataEntry extends React.Component<KeyValueProps>
     }
 
     render() {
-        let keyValueStyle: React.CSSProperties = {
+        const keyValueStyle: React.CSSProperties = {
             paddingLeft: 10,
             width: "50%",
             opacity: this.valid ? 1 : 0.5,
diff --git a/src/client/util/InteractionUtils.ts b/src/client/util/InteractionUtils.ts
index b7738e862..0c3de66ed 100644
--- a/src/client/util/InteractionUtils.ts
+++ b/src/client/util/InteractionUtils.ts
@@ -29,8 +29,8 @@ export namespace InteractionUtils {
      * @param pts - n-arbitrary long list of points
      */
     export function CenterPoint(pts: React.Touch[]): { X: number, Y: number } {
-        let centerX = pts.map(pt => pt.clientX).reduce((a, b) => a + b, 0) / pts.length;
-        let centerY = pts.map(pt => pt.clientY).reduce((a, b) => a + b, 0) / pts.length;
+        const centerX = pts.map(pt => pt.clientX).reduce((a, b) => a + b, 0) / pts.length;
+        const centerY = pts.map(pt => pt.clientY).reduce((a, b) => a + b, 0) / pts.length;
         return { X: centerX, Y: centerY };
     }
 
@@ -42,9 +42,9 @@ export namespace InteractionUtils {
      * @param oldPoint2 - previous point 2
      */
     export function Pinching(pt1: React.Touch, pt2: React.Touch, oldPoint1: React.Touch, oldPoint2: React.Touch): number {
-        let threshold = 4;
-        let oldDist = TwoPointEuclidist(oldPoint1, oldPoint2);
-        let newDist = TwoPointEuclidist(pt1, pt2);
+        const threshold = 4;
+        const oldDist = TwoPointEuclidist(oldPoint1, oldPoint2);
+        const newDist = TwoPointEuclidist(pt1, pt2);
 
         /** if they have the same sign, then we are either pinching in or out.
           * threshold it by 10 (it has to be pinching by at least threshold to be a valid pinch)
@@ -64,12 +64,12 @@ export namespace InteractionUtils {
      * @param oldPoint2 - previous point 2
      */
     export function Pinning(pt1: React.Touch, pt2: React.Touch, oldPoint1: React.Touch, oldPoint2: React.Touch): number {
-        let threshold = 4;
+        const threshold = 4;
 
-        let pt1Dist = TwoPointEuclidist(oldPoint1, pt1);
-        let pt2Dist = TwoPointEuclidist(oldPoint2, pt2);
+        const pt1Dist = TwoPointEuclidist(oldPoint1, pt1);
+        const pt2Dist = TwoPointEuclidist(oldPoint2, pt2);
 
-        let pinching = Pinching(pt1, pt2, oldPoint1, oldPoint2);
+        const pinching = Pinching(pt1, pt2, oldPoint1, oldPoint2);
 
         if (pinching !== 0) {
             if ((pt1Dist < threshold && pt2Dist > threshold) || (pt1Dist > threshold && pt2Dist < threshold)) {
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index eedc4967d..fb6f27478 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -38,16 +38,16 @@ export class LinkManager {
     }
 
     public getAllLinks(): Doc[] {
-        let ldoc = LinkManager.Instance.LinkManagerDoc;
+        const ldoc = LinkManager.Instance.LinkManagerDoc;
         if (ldoc) {
-            let docs = DocListCast(ldoc.allLinks);
+            const docs = DocListCast(ldoc.allLinks);
             return docs;
         }
         return [];
     }
 
     public addLink(linkDoc: Doc): boolean {
-        let linkList = LinkManager.Instance.getAllLinks();
+        const linkList = LinkManager.Instance.getAllLinks();
         linkList.push(linkDoc);
         if (LinkManager.Instance.LinkManagerDoc) {
             LinkManager.Instance.LinkManagerDoc.allLinks = new List<Doc>(linkList);
@@ -57,8 +57,8 @@ export class LinkManager {
     }
 
     public deleteLink(linkDoc: Doc): boolean {
-        let linkList = LinkManager.Instance.getAllLinks();
-        let index = LinkManager.Instance.getAllLinks().indexOf(linkDoc);
+        const linkList = LinkManager.Instance.getAllLinks();
+        const index = LinkManager.Instance.getAllLinks().indexOf(linkDoc);
         if (index > -1) {
             linkList.splice(index, 1);
             if (LinkManager.Instance.LinkManagerDoc) {
@@ -71,23 +71,23 @@ export class LinkManager {
 
     // finds all links that contain the given anchor
     public getAllRelatedLinks(anchor: Doc): Doc[] {//List<Doc> {
-        let related = LinkManager.Instance.getAllLinks().filter(link => {
-            let protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null));
-            let protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null));
+        const related = LinkManager.Instance.getAllLinks().filter(link => {
+            const protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null));
+            const protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null));
             return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor);
         });
         return related;
     }
 
     public deleteAllLinksOnAnchor(anchor: Doc) {
-        let related = LinkManager.Instance.getAllRelatedLinks(anchor);
+        const related = LinkManager.Instance.getAllRelatedLinks(anchor);
         related.forEach(linkDoc => LinkManager.Instance.deleteLink(linkDoc));
     }
 
     public addGroupType(groupType: string): boolean {
         if (LinkManager.Instance.LinkManagerDoc) {
             LinkManager.Instance.LinkManagerDoc[groupType] = new List<string>([]);
-            let groupTypes = LinkManager.Instance.getAllGroupTypes();
+            const groupTypes = LinkManager.Instance.getAllGroupTypes();
             groupTypes.push(groupType);
             LinkManager.Instance.LinkManagerDoc.allGroupTypes = new List<string>(groupTypes);
             return true;
@@ -99,8 +99,8 @@ export class LinkManager {
     public deleteGroupType(groupType: string): boolean {
         if (LinkManager.Instance.LinkManagerDoc) {
             if (LinkManager.Instance.LinkManagerDoc[groupType]) {
-                let groupTypes = LinkManager.Instance.getAllGroupTypes();
-                let index = groupTypes.findIndex(type => type.toUpperCase() === groupType.toUpperCase());
+                const groupTypes = LinkManager.Instance.getAllGroupTypes();
+                const index = groupTypes.findIndex(type => type.toUpperCase() === groupType.toUpperCase());
                 if (index > -1) groupTypes.splice(index, 1);
                 LinkManager.Instance.LinkManagerDoc.allGroupTypes = new List<string>(groupTypes);
                 LinkManager.Instance.LinkManagerDoc[groupType] = undefined;
@@ -146,8 +146,8 @@ export class LinkManager {
     }
 
     public addGroupToAnchor(linkDoc: Doc, anchor: Doc, groupDoc: Doc, replace: boolean = false) {
-        let groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor);
-        let index = groups.findIndex(gDoc => {
+        const groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor);
+        const index = groups.findIndex(gDoc => {
             return StrCast(groupDoc.type).toUpperCase() === StrCast(gDoc.type).toUpperCase();
         });
         if (index > -1 && replace) {
@@ -161,32 +161,32 @@ export class LinkManager {
 
     // removes group doc of given group type only from given anchor on given link
     public removeGroupFromAnchor(linkDoc: Doc, anchor: Doc, groupType: string) {
-        let groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor);
-        let newGroups = groups.filter(groupDoc => StrCast(groupDoc.type).toUpperCase() !== groupType.toUpperCase());
+        const groups = LinkManager.Instance.getAnchorGroups(linkDoc, anchor);
+        const newGroups = groups.filter(groupDoc => StrCast(groupDoc.type).toUpperCase() !== groupType.toUpperCase());
         LinkManager.Instance.setAnchorGroups(linkDoc, anchor, newGroups);
     }
 
     // returns map of group type to anchor's links in that group type
     public getRelatedGroupedLinks(anchor: Doc): Map<string, Array<Doc>> {
-        let related = this.getAllRelatedLinks(anchor);
-        let anchorGroups = new Map<string, Array<Doc>>();
+        const related = this.getAllRelatedLinks(anchor);
+        const anchorGroups = new Map<string, Array<Doc>>();
         related.forEach(link => {
-            let groups = LinkManager.Instance.getAnchorGroups(link, anchor);
+            const groups = LinkManager.Instance.getAnchorGroups(link, anchor);
 
             if (groups.length > 0) {
                 groups.forEach(groupDoc => {
-                    let groupType = StrCast(groupDoc.type);
+                    const groupType = StrCast(groupDoc.type);
                     if (groupType === "") {
-                        let group = anchorGroups.get("*");
+                        const group = anchorGroups.get("*");
                         anchorGroups.set("*", group ? [...group, link] : [link]);
                     } else {
-                        let group = anchorGroups.get(groupType);
+                        const group = anchorGroups.get(groupType);
                         anchorGroups.set(groupType, group ? [...group, link] : [link]);
                     }
                 });
             } else {
                 // if link is in no groups then put it in default group
-                let group = anchorGroups.get("*");
+                const group = anchorGroups.get("*");
                 anchorGroups.set("*", group ? [...group, link] : [link]);
             }
 
@@ -212,11 +212,11 @@ export class LinkManager {
 
     // returns a list of all metadata docs associated with the given group type
     public getAllMetadataDocsInGroup(groupType: string): Array<Doc> {
-        let md: Doc[] = [];
-        let allLinks = LinkManager.Instance.getAllLinks();
+        const md: Doc[] = [];
+        const allLinks = LinkManager.Instance.getAllLinks();
         allLinks.forEach(linkDoc => {
-            let anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, null));
-            let anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, null));
+            const anchor1Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor1, Doc, null));
+            const anchor2Groups = LinkManager.Instance.getAnchorGroups(linkDoc, Cast(linkDoc.anchor2, Doc, null));
             anchor1Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } });
             anchor2Groups.forEach(groupDoc => { if (StrCast(groupDoc.type).toUpperCase() === groupType.toUpperCase()) { const meta = Cast(groupDoc.metadata, Doc, null); meta && md.push(meta); } });
         });
@@ -225,8 +225,8 @@ export class LinkManager {
 
     // checks if a link with the given anchors exists
     public doesLinkExist(anchor1: Doc, anchor2: Doc): boolean {
-        let allLinks = LinkManager.Instance.getAllLinks();
-        let index = allLinks.findIndex(linkDoc => {
+        const allLinks = LinkManager.Instance.getAllLinks();
+        const index = allLinks.findIndex(linkDoc => {
             return (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor1) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor2)) ||
                 (Doc.AreProtosEqual(Cast(linkDoc.anchor1, Doc, null), anchor2) && Doc.AreProtosEqual(Cast(linkDoc.anchor2, Doc, null), anchor1));
         });
@@ -237,8 +237,8 @@ export class LinkManager {
     //TODO This should probably return undefined if there isn't an opposite anchor
     //TODO This should also await the return value of the anchor so we don't filter out promises
     public getOppositeAnchor(linkDoc: Doc, anchor: Doc): Doc | undefined {
-        let a1 = Cast(linkDoc.anchor1, Doc, null);
-        let a2 = Cast(linkDoc.anchor2, Doc, null);
+        const a1 = Cast(linkDoc.anchor1, Doc, null);
+        const a2 = Cast(linkDoc.anchor2, Doc, null);
         if (Doc.AreProtosEqual(anchor, a1)) return a2;
         if (Doc.AreProtosEqual(anchor, a2)) return a1;
         if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts
index 003ff6272..f1fa6f11d 100644
--- a/src/client/util/ProsemirrorExampleTransfer.ts
+++ b/src/client/util/ProsemirrorExampleTransfer.ts
@@ -4,7 +4,7 @@ import { undoInputRule } from "prosemirror-inputrules";
 import { Schema } from "prosemirror-model";
 import { liftListItem, sinkListItem } from "./prosemirrorPatches.js";
 import { splitListItem, wrapInList, } from "prosemirror-schema-list";
-import { EditorState, Transaction, TextSelection, NodeSelection } from "prosemirror-state";
+import { EditorState, Transaction, TextSelection } from "prosemirror-state";
 import { TooltipTextMenu } from "./TooltipTextMenu";
 
 const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
@@ -15,22 +15,22 @@ export let updateBullets = (tx2: Transaction, schema: Schema, mapStyle?: string)
     let fontSize: number | undefined = undefined;
     tx2.doc.descendants((node: any, offset: any, index: any) => {
         if (node.type === schema.nodes.ordered_list || node.type === schema.nodes.list_item) {
-            let path = (tx2.doc.resolve(offset) as any).path;
+            const path = (tx2.doc.resolve(offset) as any).path;
             let depth = Array.from(path).reduce((p: number, c: any) => p + (c.hasOwnProperty("type") && c.type === schema.nodes.ordered_list ? 1 : 0), 0);
             if (node.type === schema.nodes.ordered_list) depth++;
             fontSize = depth === 1 && node.attrs.setFontSize ? Number(node.attrs.setFontSize) : fontSize;
-            let fsize = fontSize && node.type === schema.nodes.ordered_list ? Math.max(6, fontSize - (depth - 1) * 4) : undefined;
+            const fsize = fontSize && node.type === schema.nodes.ordered_list ? Math.max(6, fontSize - (depth - 1) * 4) : undefined;
             tx2.setNodeMarkup(offset, node.type, { ...node.attrs, mapStyle: mapStyle ? mapStyle : node.attrs.mapStyle, bulletStyle: depth, inheritedFontSize: fsize }, node.marks);
         }
     });
     return tx2;
 };
 export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: KeyMap): KeyMap {
-    let keys: { [key: string]: any } = {}, type;
+    const keys: { [key: string]: any } = {};
 
     function bind(key: string, cmd: any) {
         if (mapKeys) {
-            let mapped = mapKeys[key];
+            const mapped = mapKeys[key];
             if (mapped === false) return;
             if (mapped) key = mapped;
         }
@@ -79,7 +79,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
     // });
 
 
-    let cmd = chainCommands(exitCode, (state, dispatch) => {
+    const cmd = chainCommands(exitCode, (state, dispatch) => {
         if (dispatch) {
             dispatch(state.tr.replaceSelectionWith(schema.nodes.hard_break.create()).scrollIntoView());
             return true;
@@ -99,7 +99,7 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
         bind("Shift-Ctrl-" + i, setBlockType(schema.nodes.heading, { level: i }));
     }
 
-    let hr = schema.nodes.horizontal_rule;
+    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;
@@ -108,18 +108,18 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
     bind("Mod-s", TooltipTextMenu.insertStar);
 
     bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        var ref = state.selection;
-        var range = ref.$from.blockRange(ref.$to);
-        var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+        const ref = state.selection;
+        const range = ref.$from.blockRange(ref.$to);
+        const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
         if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
-            let tx3 = updateBullets(tx2, schema);
+            const tx3 = updateBullets(tx2, schema);
             marks && tx3.ensureMarks([...marks]);
             marks && tx3.setStoredMarks([...marks]);
             dispatch(tx3);
         })) { // couldn't sink into an existing list, so wrap in a new one
-            let newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end)));
+            const newstate = state.applyTransaction(state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end)));
             if (!wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => {
-                let tx3 = updateBullets(tx2, schema);
+                const tx3 = updateBullets(tx2, schema);
                 // when promoting to a list, assume list will format things so don't copy the stored marks.
                 marks && tx3.ensureMarks([...marks]);
                 marks && tx3.setStoredMarks([...marks]);
@@ -131,10 +131,10 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
     });
 
     bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+        const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
 
         if (!liftListItem(schema.nodes.list_item)(state.tr, (tx2: Transaction) => {
-            let tx3 = updateBullets(tx2, schema);
+            const tx3 = updateBullets(tx2, schema);
             marks && tx3.ensureMarks([...marks]);
             marks && tx3.setStoredMarks([...marks]);
             dispatch(tx3);
@@ -143,14 +143,14 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
         }
     });
 
-    let splitMetadata = (marks: any, tx: Transaction) => {
+    const splitMetadata = (marks: any, tx: Transaction) => {
         marks && tx.ensureMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal));
         marks && tx.setStoredMarks(marks.filter((val: any) => val.type !== schema.marks.metadata && val.type !== schema.marks.metadataKey && val.type !== schema.marks.metadataVal));
         return tx;
     };
-    bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
-        if (!splitListItem(schema.nodes.list_item)(state, (tx3: Transaction) => dispatch(tx3))) {
+    bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
+        const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+        if (!splitListItem(schema.nodes.list_item)(state, dispatch)) {
             if (!splitBlockKeepMarks(state, (tx3: Transaction) => {
                 splitMetadata(marks, tx3);
                 if (!liftListItem(schema.nodes.list_item)(tx3, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) {
@@ -163,18 +163,18 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
         return true;
     });
     bind("Space", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+        const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
         dispatch(splitMetadata(marks, state.tr));
         return false;
     });
     bind(":", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
-        let range = state.selection.$from.blockRange(state.selection.$to, (node: any) => {
+        const range = state.selection.$from.blockRange(state.selection.$to, (node: any) => {
             return !node.marks || !node.marks.find((m: any) => m.type === schema.marks.metadata);
         });
-        let path = (state.doc.resolve(state.selection.from - 1) as any).path;
-        let spaceSeparator = path[path.length - 3].childCount > 1 ? 0 : -1;
-        let textsel = TextSelection.create(state.doc, range!.end - path[path.length - 3].lastChild.nodeSize + spaceSeparator, range!.end);
-        let text = range ? state.doc.textBetween(textsel.from, textsel.to) : "";
+        const path = (state.doc.resolve(state.selection.from - 1) as any).path;
+        const spaceSeparator = path[path.length - 3].childCount > 1 ? 0 : -1;
+        const textsel = TextSelection.create(state.doc, range!.end - path[path.length - 3].lastChild.nodeSize + spaceSeparator, range!.end);
+        const text = range ? state.doc.textBetween(textsel.from, textsel.to) : "";
         let whitespace = text.length - 1;
         for (; whitespace >= 0 && text[whitespace] !== " "; whitespace--) { }
         if (text.endsWith(":")) {
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index f4c44e5ce..1a637df32 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -62,109 +62,109 @@ export const inpRules = {
         new InputRule(
             new RegExp(/^#([0-9]+)\s$/),
             (state, match, start, end) => {
-                let size = Number(match[1]);
-                let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const size = Number(match[1]);
+                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
                 if (ruleProvider && heading) {
-                    (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = Number(match[1]);
+                    (Cast(FormattedTextBox.InputBoxOverlay!.props.Document, Doc) as Doc).heading = size;
                     return state.tr.deleteRange(start, end);
                 }
-                return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: Number(match[1]) }));
+                return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size }));
             }),
         new InputRule(
             new RegExp(/t/),
             (state, match, start, end) => {
                 if (state.selection.to === state.selection.from) return null;
-                let node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = (state.doc.resolve(start) as any).nodeAfter;
                 return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "todo", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr;
             }),
         new InputRule(
             new RegExp(/i/),
             (state, match, start, end) => {
                 if (state.selection.to === state.selection.from) return null;
-                let node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = (state.doc.resolve(start) as any).nodeAfter;
                 return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "ignore", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr;
             }),
         new InputRule(
             new RegExp(/\!/),
             (state, match, start, end) => {
                 if (state.selection.to === state.selection.from) return null;
-                let node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = (state.doc.resolve(start) as any).nodeAfter;
                 return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "important", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr;
             }),
         new InputRule(
             new RegExp(/\x/),
             (state, match, start, end) => {
                 if (state.selection.to === state.selection.from) return null;
-                let node = (state.doc.resolve(start) as any).nodeAfter;
+                const node = (state.doc.resolve(start) as any).nodeAfter;
                 return node ? state.tr.addMark(start, end, schema.marks.user_tag.create({ userid: Doc.CurrentUserEmail, tag: "disagree", modified: Math.round(Date.now() / 1000 / 60) })) : state.tr;
             }),
         new InputRule(
             new RegExp(/^\^\^\s$/),
             (state, match, start, end) => {
-                let node = (state.doc.resolve(start) as any).nodeAfter;
-                let sm = state.storedMarks || undefined;
-                let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const sm = state.storedMarks || undefined;
+                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "center";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
                 }
-                let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "center" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
+                const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "center" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
             }),
         new InputRule(
             new RegExp(/^\[\[\s$/),
             (state, match, start, end) => {
-                let node = (state.doc.resolve(start) as any).nodeAfter;
-                let sm = state.storedMarks || undefined;
-                let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const sm = state.storedMarks || undefined;
+                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "left";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
                 }
-                let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "left" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
+                const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "left" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
             }),
         new InputRule(
             new RegExp(/^\]\]\s$/),
             (state, match, start, end) => {
-                let node = (state.doc.resolve(start) as any).nodeAfter;
-                let sm = state.storedMarks || undefined;
-                let ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
-                let heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
+                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const sm = state.storedMarks || undefined;
+                const ruleProvider = FormattedTextBox.InputBoxOverlay!.props.ruleProvider;
+                const heading = NumCast(FormattedTextBox.InputBoxOverlay!.props.Document.heading);
                 if (ruleProvider && heading) {
                     ruleProvider["ruleAlign_" + heading] = "right";
                     return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
                 }
-                let replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "right" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
+                const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "right" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
             }),
         new InputRule(
             new RegExp(/##\s$/),
             (state, match, start, end) => {
-                let target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" });
-                let node = (state.doc.resolve(start) as any).nodeAfter;
-                let newNode = schema.nodes.dashComment.create({ docid: target[Id] });
-                let dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" });
-                let sm = state.storedMarks || undefined;
-                let replaced = node ? state.tr.insert(start, newNode).replaceRangeWith(start + 1, end + 1, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
+                const target = Docs.Create.TextDocument({ width: 75, height: 35, autoHeight: true, fontSize: 9, title: "inline comment" });
+                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const newNode = schema.nodes.dashComment.create({ docid: target[Id] });
+                const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" });
+                const sm = state.storedMarks || undefined;
+                const replaced = node ? state.tr.insert(start, newNode).replaceRangeWith(start + 1, end + 1, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced;//.setSelection(new NodeSelection(replaced.doc.resolve(end)));
             }),
         new InputRule(
             new RegExp(/\(\(/),
             (state, match, start, end) => {
-                let node = (state.doc.resolve(start) as any).nodeAfter;
-                let sm = state.storedMarks || undefined;
-                let mark = state.schema.marks.highlight.create();
-                let selected = state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).addMark(start, end, mark);
-                let content = selected.selection.content();
-                let replaced = node ? selected.replaceRangeWith(start, start,
+                const node = (state.doc.resolve(start) as any).nodeAfter;
+                const sm = state.storedMarks || undefined;
+                const mark = state.schema.marks.highlight.create();
+                const selected = state.tr.setSelection(new TextSelection(state.doc.resolve(start), state.doc.resolve(end))).addMark(start, end, mark);
+                const content = selected.selection.content();
+                const replaced = node ? selected.replaceRangeWith(start, start,
                     schema.nodes.star.create({ visibility: true, text: content, textslice: content.toJSON() })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end + 1)));
@@ -172,14 +172,14 @@ export const inpRules = {
         new InputRule(
             new RegExp(/\)\)/),
             (state, match, start, end) => {
-                let mark = state.schema.marks.highlight.create();
+                const mark = state.schema.marks.highlight.create();
                 return state.tr.removeStoredMark(mark);
             }),
         new InputRule(
             new RegExp(/\^f\s$/),
             (state, match, start, end) => {
-                let newNode = schema.nodes.footnote.create({});
-                let tr = state.tr;
+                const newNode = schema.nodes.footnote.create({});
+                const tr = state.tr;
                 tr.deleteRange(start, end).replaceSelectionWith(newNode); // replace insertion with a footnote.
                 return tr.setSelection(new NodeSelection( // select the footnote node to open its display
                     tr.doc.resolve(  // get the location of the footnote node by subtracting the nodesize of the footnote from the current insertion point anchor (which will be immediately after the footnote node)
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 522232e9f..cb03892f3 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -1,4 +1,4 @@
-import { action, observable, runInAction, reaction, IReactionDisposer } from "mobx";
+import { reaction, IReactionDisposer } from "mobx";
 import { baseKeymap, toggleMark } from "prosemirror-commands";
 import { redo, undo } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
@@ -257,9 +257,9 @@ export const nodes: { [index: string]: NodeSpec } = {
             if (node.attrs.mapStyle === "bullet") return ['ul', 0];
             const decMap = bs ? "decimal" + bs : "";
             const multiMap = bs === 1 ? "decimal1" : bs === 2 ? "upper-alpha" : bs === 3 ? "lower-roman" : bs === 4 ? "lower-alpha" : "";
-            let map = node.attrs.mapStyle === "decimal" ? decMap : multiMap;
-            let fsize = node.attrs.setFontSize ? node.attrs.setFontSize : node.attrs.inheritedFontSize;
-            let ffam = node.attrs.setFontFamily;
+            const map = node.attrs.mapStyle === "decimal" ? decMap : multiMap;
+            const fsize = node.attrs.setFontSize ? node.attrs.setFontSize : node.attrs.inheritedFontSize;
+            const ffam = node.attrs.setFontFamily;
             return node.attrs.visibility ? ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}` }, 0] :
                 ['ol', { class: `${map}-ol`, style: `list-style: none; font-size: ${fsize}; font-family: ${ffam}` }];
         }
@@ -287,7 +287,7 @@ export const nodes: { [index: string]: NodeSpec } = {
             const bs = node.attrs.bulletStyle;
             const decMap = bs ? "decimal" + bs : "";
             const multiMap = bs === 1 ? "decimal1" : bs === 2 ? "upper-alpha" : bs === 3 ? "lower-roman" : bs === 4 ? "lower-alpha" : "";
-            let map = node.attrs.mapStyle === "decimal" ? decMap : node.attrs.mapStyle === "multi" ? multiMap : "";
+            const map = node.attrs.mapStyle === "decimal" ? decMap : node.attrs.mapStyle === "multi" ? multiMap : "";
             return node.attrs.visibility ? ["li", { class: `${map}` }, 0] : ["li", { class: `${map}` }, "..."];
             //return ["li", { class: `${map}` }, 0];
         }
@@ -432,7 +432,7 @@ export const marks: { [index: string]: MarkSpec } = {
                 tag: "span",
                 getAttrs: (p: any) => {
                     if (typeof (p) !== "string") {
-                        let style = getComputedStyle(p);
+                        const style = getComputedStyle(p);
                         if (style.textDecoration === "underline") return null;
                         if (p.parentElement.outerHTML.indexOf("text-decoration: underline") !== -1 &&
                             p.parentElement.outerHTML.indexOf("text-decoration-style: dotted") !== -1) {
@@ -457,7 +457,7 @@ export const marks: { [index: string]: MarkSpec } = {
                 tag: "span",
                 getAttrs: (p: any) => {
                     if (typeof (p) !== "string") {
-                        let style = getComputedStyle(p);
+                        const style = getComputedStyle(p);
                         if (style.textDecoration === "underline" || p.parentElement.outerHTML.indexOf("text-decoration-style:line") !== -1) {
                             return null;
                         }
@@ -493,11 +493,11 @@ export const marks: { [index: string]: MarkSpec } = {
         },
         group: "inline",
         toDOM(node: any) {
-            let uid = node.attrs.userid.replace(".", "").replace("@", "");
-            let min = Math.round(node.attrs.modified / 12);
-            let hr = Math.round(min / 60);
-            let day = Math.round(hr / 60 / 24);
-            let remote = node.attrs.userid !== Doc.CurrentUserEmail ? " userMark-remote" : "";
+            const uid = node.attrs.userid.replace(".", "").replace("@", "");
+            const min = Math.round(node.attrs.modified / 12);
+            const hr = Math.round(min / 60);
+            const day = Math.round(hr / 60 / 24);
+            const remote = node.attrs.userid !== Doc.CurrentUserEmail ? " userMark-remote" : "";
             return node.attrs.opened ?
                 ['span', { class: "userMark-" + uid + remote + " userMark-min-" + min + " userMark-hr-" + hr + " userMark-day-" + day }, 0] :
                 ['span', { class: "userMark-" + uid + remote + " userMark-min-" + min + " userMark-hr-" + hr + " userMark-day-" + day }, ['span', 0]];
@@ -513,7 +513,7 @@ export const marks: { [index: string]: MarkSpec } = {
         },
         group: "inline",
         toDOM(node: any) {
-            let uid = node.attrs.userid.replace(".", "").replace("@", "");
+            const uid = node.attrs.userid.replace(".", "").replace("@", "");
             return node.attrs.opened ?
                 ['span', { class: "userTag-" + uid + " userTag-" + node.attrs.tag }, 0] :
                 ['span', { class: "userTag-" + uid + " userTag-" + node.attrs.tag }, ['span', 0]];
@@ -534,7 +534,7 @@ export const marks: { [index: string]: MarkSpec } = {
         },
         parseDOM: [{
             tag: "span", getAttrs(dom: any) {
-                let cstyle = getComputedStyle(dom);
+                const cstyle = getComputedStyle(dom);
                 if (cstyle.font) {
                     if (cstyle.font.indexOf("Times New Roman") !== -1) return { family: "Times New Roman" };
                     if (cstyle.font.indexOf("Arial") !== -1) return { family: "Arial" };
@@ -599,7 +599,7 @@ export class ImageResizeView {
         this._handle.style.display = "none";
         this._handle.style.bottom = "-10px";
         this._handle.style.right = "-10px";
-        let self = this;
+        const self = this;
         this._img.onclick = function (e: any) {
             e.stopPropagation();
             e.preventDefault();
@@ -620,8 +620,8 @@ export class ImageResizeView {
         this._handle.onpointerdown = function (e: any) {
             e.preventDefault();
             e.stopPropagation();
-            let wid = Number(getComputedStyle(self._img).width.replace(/px/, ""));
-            let hgt = Number(getComputedStyle(self._img).height.replace(/px/, ""));
+            const wid = Number(getComputedStyle(self._img).width.replace(/px/, ""));
+            const hgt = Number(getComputedStyle(self._img).height.replace(/px/, ""));
             const startX = e.pageX;
             const startWidth = parseFloat(node.attrs.width);
             const onpointermove = (e: any) => {
@@ -634,7 +634,7 @@ export class ImageResizeView {
             const onpointerup = () => {
                 document.removeEventListener("pointermove", onpointermove);
                 document.removeEventListener("pointerup", onpointerup);
-                let pos = view.state.selection.from;
+                const pos = view.state.selection.from;
                 view.dispatch(view.state.tr.setNodeMarkup(getPos(), null, { ...node.attrs, width: self._outer.style.width, height: self._outer.style.height }));
                 view.dispatch(view.state.tr.setSelection(new NodeSelection(view.state.doc.resolve(pos))));
             };
@@ -671,19 +671,19 @@ export class DashDocCommentView {
         this._collapsed.id = "DashDocCommentView-" + node.attrs.docid;
         this._view = view;
         this._collapsed.onpointerdown = (e: any) => {
-            let node = view.state.doc.nodeAt(getPos() + 1);
+            const node = view.state.doc.nodeAt(getPos() + 1);
             view.dispatch(view.state.tr.
                 setNodeMarkup(getPos() + 1, undefined, { ...node.attrs, hidden: node.attrs.hidden ? false : true })); // update the attrs 
             setTimeout(() => node.attrs.hidden && DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc)), 100);
-        }
+        };
         this._collapsed.onpointerenter = (e: any) => {
-            let node = view.state.doc.nodeAt(getPos() + 1);
+            const node = view.state.doc.nodeAt(getPos() + 1);
             DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowHighlight(dashDoc));
             e.preventDefault();
             e.stopPropagation();
         };
         this._collapsed.onpointerleave = (e: any) => {
-            let node = view.state.doc.nodeAt(getPos() + 1);
+            const node = view.state.doc.nodeAt(getPos() + 1);
             DocServer.GetRefField(node.attrs.docid).then(async dashDoc => dashDoc instanceof Doc && Doc.linkFollowUnhighlight());
             e.preventDefault();
             e.stopPropagation();
@@ -701,7 +701,7 @@ export class DashDocView {
     _textBox: FormattedTextBox;
 
     getDocTransform = () => {
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer);
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer);
         return new Transform(-translateX, -translateY, 1).scale(1 / this.contentScaling() / scale);
     }
     contentScaling = () => NumCast(this._dashDoc!.nativeWidth) > 0 && !this._dashDoc!.ignoreAspect ? this._dashDoc![WidthSym]() / NumCast(this._dashDoc!.nativeWidth) : 1;
@@ -721,24 +721,24 @@ export class DashDocView {
         this._dashSpan.style.position = "absolute";
         this._dashSpan.style.display = "inline-block";
         this._dashSpan.style.borderWidth = "4";
-        let removeDoc = () => {
-            let pos = getPos();
-            let ns = new NodeSelection(view.state.doc.resolve(pos));
+        const removeDoc = () => {
+            const pos = getPos();
+            const ns = new NodeSelection(view.state.doc.resolve(pos));
             view.dispatch(view.state.tr.setSelection(ns).deleteSelection());
             return true;
         };
         this._dashSpan.onpointerleave = () => {
-            let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
+            const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
             if (ele) {
                 (ele as HTMLDivElement).style.backgroundColor = "";
             }
-        }
+        };
         this._dashSpan.onpointerenter = () => {
-            let ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
+            const ele = document.getElementById("DashDocCommentView-" + node.attrs.docid);
             if (ele) {
                 (ele as HTMLDivElement).style.backgroundColor = "orange";
             }
-        }
+        };
         DocServer.GetRefField(node.attrs.docid).then(async dashDoc => {
             if (dashDoc instanceof Doc) {
                 self._dashDoc = dashDoc;
@@ -777,7 +777,7 @@ export class DashDocView {
                 />, this._dashSpan);
             }
         });
-        let self = this;
+        const self = this;
         this._dashSpan.onkeydown = function (e: any) { e.stopPropagation(); };
         this._dashSpan.onkeypress = function (e: any) { e.stopPropagation(); };
         this._dashSpan.onwheel = function (e: any) { e.preventDefault(); };
@@ -830,7 +830,7 @@ export class FootnoteView {
     }
     open() {
         // Append a tooltip to the outer node
-        let tooltip = this.dom.appendChild(document.createElement("div"));
+        const tooltip = this.dom.appendChild(document.createElement("div"));
         tooltip.className = "footnote-tooltip";
         // And put a sub-ProseMirror into that
         this.innerView = new EditorView(tooltip, {
@@ -885,14 +885,14 @@ export class FootnoteView {
         this.dom.textContent = "";
     }
     dispatchInner(tr: any) {
-        let { state, transactions } = this.innerView.state.applyTransaction(tr);
+        const { state, transactions } = this.innerView.state.applyTransaction(tr);
         this.innerView.updateState(state);
 
         if (!tr.getMeta("fromOutside")) {
-            let outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1);
-            for (let transaction of transactions) {
-                let steps = transaction.steps;
-                for (let step of steps) {
+            const outerTr = this.outerView.state.tr, offsetMap = StepMap.offset(this.getPos() + 1);
+            for (const transaction of transactions) {
+                const steps = transaction.steps;
+                for (const step of steps) {
                     outerTr.step(step.map(offsetMap));
                 }
             }
@@ -903,11 +903,11 @@ export class FootnoteView {
         if (!node.sameMarkup(this.node)) return false;
         this.node = node;
         if (this.innerView) {
-            let state = this.innerView.state;
-            let start = node.content.findDiffStart(state.doc.content);
+            const state = this.innerView.state;
+            const start = node.content.findDiffStart(state.doc.content);
             if (start !== null) {
                 let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content);
-                let overlap = start - Math.min(endA, endB);
+                const overlap = start - Math.min(endA, endB);
                 if (overlap > 0) { endA += overlap; endB += overlap; }
                 this.innerView.dispatch(
                     state.tr
@@ -967,10 +967,10 @@ export class SummarizedView {
     className = (visible: boolean) => "formattedTextBox-summarizer" + (visible ? "" : "-collapsed");
 
     updateSummarizedText(start?: any) {
-        let mark = this._view.state.schema.marks.highlight.create();
+        const mark = this._view.state.schema.marks.highlight.create();
         let endPos = start;
 
-        let visited = new Set();
+        const visited = new Set();
         for (let i: number = start + 1; i < this._view.state.doc.nodeSize - 1; i++) {
             let skip = false;
             this._view.state.doc.nodesBetween(start, i, (node: Node, pos: number, parent: Node, index: number) => {
@@ -999,7 +999,7 @@ export const schema = new Schema({ nodes, marks });
 const fromJson = schema.nodeFromJSON;
 
 schema.nodeFromJSON = (json: any) => {
-    let node = fromJson(json);
+    const node = fromJson(json);
     if (json.type === "star") {
         node.attrs.text = Slice.fromJSON(schema, node.attrs.textslice);
     }
diff --git a/src/client/util/Scripting.ts b/src/client/util/Scripting.ts
index ff4451824..0fa96963e 100644
--- a/src/client/util/Scripting.ts
+++ b/src/client/util/Scripting.ts
@@ -94,16 +94,16 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
         return { compiled: false, errors: diagnostics };
     }
 
-    let paramNames = Object.keys(scriptingGlobals);
-    let params = paramNames.map(key => scriptingGlobals[key]);
+    const paramNames = Object.keys(scriptingGlobals);
+    const params = paramNames.map(key => scriptingGlobals[key]);
     // let fieldTypes = [Doc, ImageField, PdfField, VideoField, AudioField, List, RichTextField, ScriptField, ComputedField, CompileScript];
     // let paramNames = ["Docs", ...fieldTypes.map(fn => fn.name)];
     // let params: any[] = [Docs, ...fieldTypes];
-    let compiledFunction = new Function(...paramNames, `return ${script}`);
-    let { capturedVariables = {} } = options;
-    let run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => {
-        let argsArray: any[] = [];
-        for (let name of customParams) {
+    const compiledFunction = new Function(...paramNames, `return ${script}`);
+    const { capturedVariables = {} } = options;
+    const run = (args: { [name: string]: any } = {}, onError?: (e: any) => void, errorVal?: any): ScriptResult => {
+        const argsArray: any[] = [];
+        for (const name of customParams) {
             if (name === "this") {
                 continue;
             }
@@ -113,7 +113,7 @@ function Run(script: string | undefined, customParams: string[], diagnostics: an
                 argsArray.push(capturedVariables[name]);
             }
         }
-        let thisParam = args.this || capturedVariables.this;
+        const thisParam = args.this || capturedVariables.this;
         let batch: { end(): void } | undefined = undefined;
         try {
             if (!options.editable) {
@@ -146,7 +146,7 @@ class ScriptingCompilerHost {
 
     // getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): ts.SourceFile | undefined {
     getSourceFile(fileName: string, languageVersion: any, onError?: ((message: string) => void) | undefined, shouldCreateNewSourceFile?: boolean | undefined): any | undefined {
-        let contents = this.readFile(fileName);
+        const contents = this.readFile(fileName);
         if (contents !== undefined) {
             return ts.createSourceFile(fileName, contents, languageVersion, true);
         }
@@ -180,7 +180,7 @@ class ScriptingCompilerHost {
         return this.files.some(file => file.fileName === fileName);
     }
     readFile(fileName: string): string | undefined {
-        let file = this.files.find(file => file.fileName === fileName);
+        const file = this.files.find(file => file.fileName === fileName);
         if (file) {
             return file.content;
         }
@@ -218,7 +218,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
     if (options.globals) {
         Scripting.setScriptingGlobals(options.globals);
     }
-    let host = new ScriptingCompilerHost;
+    const host = new ScriptingCompilerHost;
     if (options.traverser) {
         const sourceFile = ts.createSourceFile('script.ts', script, ts.ScriptTarget.ES2015, true);
         const onEnter = typeof options.traverser === "object" ? options.traverser.onEnter : options.traverser;
@@ -240,7 +240,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
         script = printer.printFile(transformed[0]);
         result.dispose();
     }
-    let paramNames: string[] = [];
+    const paramNames: string[] = [];
     if ("this" in params || "this" in capturedVariables) {
         paramNames.push("this");
     }
@@ -248,7 +248,7 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
         if (key === "this") continue;
         paramNames.push(key);
     }
-    let paramList = paramNames.map(key => {
+    const paramList = paramNames.map(key => {
         const val = params[key];
         return `${key}: ${val}`;
     });
@@ -258,18 +258,18 @@ export function CompileScript(script: string, options: ScriptOptions = {}): Comp
         paramNames.push(key);
         paramList.push(`${key}: ${typeof val === "object" ? Object.getPrototypeOf(val).constructor.name : typeof val}`);
     }
-    let paramString = paramList.join(", ");
-    let funcScript = `(function(${paramString})${requiredType ? `: ${requiredType}` : ''} {
+    const paramString = paramList.join(", ");
+    const funcScript = `(function(${paramString})${requiredType ? `: ${requiredType}` : ''} {
         ${addReturn ? `return ${script};` : script}
     })`;
     host.writeFile("file.ts", funcScript);
 
     if (typecheck) host.writeFile('node_modules/typescript/lib/lib.d.ts', typescriptlib);
-    let program = ts.createProgram(["file.ts"], {}, host);
-    let testResult = program.emit();
-    let outputText = host.readFile("file.js");
+    const program = ts.createProgram(["file.ts"], {}, host);
+    const testResult = program.emit();
+    const outputText = host.readFile("file.js");
 
-    let diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics);
+    const diagnostics = ts.getPreEmitDiagnostics(program).concat(testResult.diagnostics);
 
     const result = Run(outputText, paramNames, diagnostics, script, options);
 
diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 2cf13680a..7a9176bec 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -34,36 +34,36 @@ export namespace SearchUtil {
     export function Search(query: string, returnDocs: false, options?: SearchParams): Promise<IdSearchResult>;
     export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) {
         query = query || "*"; //If we just have a filter query, search for * as the query
-        let result: IdSearchResult = JSON.parse(await rp.get(Utils.prepend("/search"), {
+        const result: IdSearchResult = JSON.parse(await rp.get(Utils.prepend("/search"), {
             qs: { ...options, q: query },
         }));
         if (!returnDocs) {
             return result;
         }
 
-        let { ids, numFound, highlighting } = result;
+        const { ids, highlighting } = result;
 
-        let txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), {
+        const txtresult = query !== "*" && JSON.parse(await rp.get(Utils.prepend("/textsearch"), {
             qs: { ...options, q: query },
         }));
 
-        let fileids = txtresult ? txtresult.ids : [];
-        let newIds: string[] = [];
-        let newLines: string[][] = [];
+        const fileids = txtresult ? txtresult.ids : [];
+        const newIds: string[] = [];
+        const newLines: string[][] = [];
         await Promise.all(fileids.map(async (tr: string, i: number) => {
-            let docQuery = "fileUpload_t:" + tr.substr(0, 7); //If we just have a filter query, search for * as the query
-            let docResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: docQuery } }));
+            const docQuery = "fileUpload_t:" + tr.substr(0, 7); //If we just have a filter query, search for * as the query
+            const docResult = JSON.parse(await rp.get(Utils.prepend("/search"), { qs: { ...options, q: docQuery } }));
             newIds.push(...docResult.ids);
             newLines.push(...docResult.ids.map((dr: any) => txtresult.lines[i]));
         }));
 
 
-        let theDocs: Doc[] = [];
-        let theLines: string[][] = [];
+        const theDocs: Doc[] = [];
+        const theLines: string[][] = [];
         const textDocMap = await DocServer.GetRefFields(newIds);
         const textDocs = newIds.map((id: string) => textDocMap[id]).map(doc => doc as Doc);
         for (let i = 0; i < textDocs.length; i++) {
-            let testDoc = textDocs[i];
+            const testDoc = textDocs[i];
             if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1) {
                 theDocs.push(Doc.GetProto(testDoc));
                 theLines.push(newLines[i].map(line => line.replace(query, query.toUpperCase())));
@@ -73,7 +73,7 @@ export namespace SearchUtil {
         const docMap = await DocServer.GetRefFields(ids);
         const docs = ids.map((id: string) => docMap[id]).map(doc => doc as Doc);
         for (let i = 0; i < ids.length; i++) {
-            let testDoc = docs[i];
+            const testDoc = docs[i];
             if (testDoc instanceof Doc && testDoc.type !== DocumentType.KVP && (options.allowAliases || theDocs.findIndex(d => Doc.AreProtosEqual(d, testDoc)) === -1)) {
                 theDocs.push(testDoc);
                 theLines.push([]);
diff --git a/src/client/util/SerializationHelper.ts b/src/client/util/SerializationHelper.ts
index ff048f647..1f6b939d3 100644
--- a/src/client/util/SerializationHelper.ts
+++ b/src/client/util/SerializationHelper.ts
@@ -1,7 +1,6 @@
-import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema, primitive, SKIP } from "serializr";
-import { Field, Doc } from "../../new_fields/Doc";
+import { PropSchema, serialize, deserialize, custom, setDefaultModelSchema, getDefaultModelSchema } from "serializr";
+import { Field } from "../../new_fields/Doc";
 import { ClientUtils } from "./ClientUtils";
-import { emptyFunction } from "../../Utils";
 
 let serializing = 0;
 export function afterDocDeserialize(cb: (err: any, val: any) => void, err: any, newValue: any) {
@@ -65,8 +64,8 @@ export namespace SerializationHelper {
     }
 }
 
-let serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void | Promise<any> } } = {};
-let reverseMap: { [ctor: string]: string } = {};
+const serializationTypes: { [name: string]: { ctor: { new(): any }, afterDeserialize?: (obj: any) => void | Promise<any> } } = {};
+const reverseMap: { [ctor: string]: string } = {};
 
 export interface DeserializableOpts {
     (constructor: { new(...args: any[]): any }): void;
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index cc1d628b1..7496ac73c 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -9,7 +9,6 @@ import { Utils } from "../../Utils";
 import "./SharingManager.scss";
 import { Id } from "../../new_fields/FieldSymbols";
 import { observer } from "mobx-react";
-import { MainView } from "../views/MainView";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import * as fa from '@fortawesome/free-solid-svg-icons';
@@ -103,10 +102,10 @@ export default class SharingManager extends React.Component<{}> {
     }
 
     populateUsers = async () => {
-        let userList = await RequestPromise.get(Utils.prepend("/getUsers"));
+        const userList = await RequestPromise.get(Utils.prepend("/getUsers"));
         const raw = JSON.parse(userList) as User[];
         const evaluating = raw.map(async user => {
-            let isCandidate = user.email !== Doc.CurrentUserEmail;
+            const isCandidate = user.email !== Doc.CurrentUserEmail;
             if (isCandidate) {
                 const userDocument = await DocServer.GetRefField(user.userDocumentId);
                 if (userDocument instanceof Doc) {
@@ -130,7 +129,7 @@ export default class SharingManager extends React.Component<{}> {
         if (state === SharingPermissions.None) {
             const metadata = (await DocCastAsync(manager[key]));
             if (metadata) {
-                let sharedAlias = (await DocCastAsync(metadata.sharedAlias))!;
+                const sharedAlias = (await DocCastAsync(metadata.sharedAlias))!;
                 Doc.RemoveDocFromList(notificationDoc, storage, sharedAlias);
                 manager[key] = undefined;
             }
@@ -145,7 +144,7 @@ export default class SharingManager extends React.Component<{}> {
     }
 
     private setExternalSharing = (state: string) => {
-        let sharingDoc = this.sharingDoc;
+        const sharingDoc = this.sharingDoc;
         if (!sharingDoc) {
             return;
         }
@@ -156,7 +155,7 @@ export default class SharingManager extends React.Component<{}> {
         if (!this.targetDoc) {
             return undefined;
         }
-        let baseUrl = Utils.prepend("/doc/" + this.targetDoc[Id]);
+        const baseUrl = Utils.prepend("/doc/" + this.targetDoc[Id]);
         return `${baseUrl}?sharing=true`;
     }
 
@@ -178,7 +177,7 @@ export default class SharingManager extends React.Component<{}> {
     }
 
     private focusOn = (contents: string) => {
-        let title = this.targetDoc ? StrCast(this.targetDoc.title) : "";
+        const title = this.targetDoc ? StrCast(this.targetDoc.title) : "";
         return (
             <span
                 className={"focus-span"}
diff --git a/src/client/util/TooltipLinkingMenu.tsx b/src/client/util/TooltipLinkingMenu.tsx
index e6d6c471f..b46675a04 100644
--- a/src/client/util/TooltipLinkingMenu.tsx
+++ b/src/client/util/TooltipLinkingMenu.tsx
@@ -2,10 +2,6 @@ import { EditorState } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { FieldViewProps } from "../views/nodes/FieldView";
 import "./TooltipTextMenu.scss";
-import React = require("react");
-const { toggleMark, setBlockType, wrapIn } = require("prosemirror-commands");
-
-const SVG = "http://www.w3.org/2000/svg";
 
 //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc.
 export class TooltipLinkingMenu {
@@ -23,9 +19,9 @@ export class TooltipLinkingMenu {
         //add the div which is the tooltip
         view.dom.parentNode!.parentNode!.appendChild(this.tooltip);
 
-        let target = "https://www.google.com";
+        const target = "https://www.google.com";
 
-        let link = document.createElement("a");
+        const link = document.createElement("a");
         link.href = target;
         link.textContent = target;
         link.target = "_blank";
@@ -37,7 +33,7 @@ export class TooltipLinkingMenu {
 
     //updates the tooltip menu when the selection changes
     update(view: EditorView, lastState: EditorState | undefined) {
-        let state = view.state;
+        const state = view.state;
         // Don't do anything if the document/selection didn't change
         if (lastState && lastState.doc.eq(state.doc) &&
             lastState.selection.eq(state.selection)) return;
@@ -53,16 +49,16 @@ export class TooltipLinkingMenu {
 
         // Otherwise, reposition it and update its content
         this.tooltip.style.display = "";
-        let { from, to } = state.selection;
-        let start = view.coordsAtPos(from), end = view.coordsAtPos(to);
+        const { from, to } = state.selection;
+        const start = view.coordsAtPos(from), end = view.coordsAtPos(to);
         // The box in which the tooltip is positioned, to use as base
-        let box = this.tooltip.offsetParent!.getBoundingClientRect();
+        const box = this.tooltip.offsetParent!.getBoundingClientRect();
         // Find a center-ish x position from the selection endpoints (when
         // crossing lines, end may be more to the left)
-        let left = Math.max((start.left + end.left) / 2, start.left + 3);
+        const left = Math.max((start.left + end.left) / 2, start.left + 3);
         this.tooltip.style.left = (left - box.left) * this.editorProps.ScreenToLocalTransform().Scale + "px";
-        let width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale;
-        let mid = Math.min(start.left, end.left) + width;
+        const width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale;
+        const mid = Math.min(start.left, end.left) + width;
 
         this.tooltip.style.width = "auto";
         this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px";
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 5136089b3..5e777cef9 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -2,7 +2,7 @@ import { action } from "mobx";
 import { Dropdown, icons, MenuItem } from "prosemirror-menu"; //no import css
 import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos, Schema } from "prosemirror-model";
 import { wrapInList } from 'prosemirror-schema-list';
-import { EditorState, NodeSelection, TextSelection, Transaction } from "prosemirror-state";
+import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc, Field, Opt } from "../../new_fields/Doc";
 import { Id } from "../../new_fields/FieldSymbols";
@@ -86,7 +86,7 @@ export class TooltipTextMenu {
         this.basicTools.className = "basic-tools";
 
         // init buttons to the tooltip -- paths to svgs are obtained from fontawesome
-        let items = [
+        const items = [
             { command: toggleMark(schema.marks.strong), dom: this.svgIcon("strong", "Bold", "M333.49 238a122 122 0 0 0 27-65.21C367.87 96.49 308 32 233.42 32H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h31.87v288H34a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h209.32c70.8 0 134.14-51.75 141-122.4 4.74-48.45-16.39-92.06-50.83-119.6zM145.66 112h87.76a48 48 0 0 1 0 96h-87.76zm87.76 288h-87.76V288h87.76a56 56 0 0 1 0 112z") },
             { command: toggleMark(schema.marks.em), dom: this.svgIcon("em", "Italic", "M320 48v32a16 16 0 0 1-16 16h-62.76l-80 320H208a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h62.76l80-320H112a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h192a16 16 0 0 1 16 16z") },
             { command: toggleMark(schema.marks.underline), dom: this.svgIcon("underline", "Underline", "M32 64h32v160c0 88.22 71.78 160 160 160s160-71.78 160-160V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H272a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h32v160a80 80 0 0 1-160 0V64h32a16 16 0 0 0 16-16V16a16 16 0 0 0-16-16H32a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm400 384H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z") },
@@ -145,7 +145,7 @@ export class TooltipTextMenu {
 
         // link menu
         this.updateLinkMenu();
-        let dropdown = await this.createLinkDropdown();
+        const dropdown = await this.createLinkDropdown();
         this._linkDropdownDom = dropdown.render(this.view).dom;
         this.tooltip.appendChild(this._linkDropdownDom);
 
@@ -209,17 +209,17 @@ export class TooltipTextMenu {
     // creates dragger element that allows dragging and collapsing (on double click) 
     // of editor and appends it to the wrapper
     createDragger() {
-        let draggerWrapper = document.createElement("div");
+        const draggerWrapper = document.createElement("div");
         draggerWrapper.className = "dragger-wrapper";
 
-        let dragger = document.createElement("div");
+        const dragger = document.createElement("div");
         dragger.className = "dragger";
 
-        let line1 = document.createElement("span");
+        const line1 = document.createElement("span");
         line1.className = "dragger-line";
-        let line2 = document.createElement("span");
+        const line2 = document.createElement("span");
         line2.className = "dragger-line";
-        let line3 = document.createElement("span");
+        const line3 = document.createElement("span");
         line3.className = "dragger-line";
 
         dragger.appendChild(line1);
@@ -293,12 +293,12 @@ export class TooltipTextMenu {
     //label of dropdown will change to given label
     updateFontSizeDropdown(label: string) {
         //font SIZES
-        let fontSizeBtns: MenuItem[] = [];
+        const fontSizeBtns: MenuItem[] = [];
         this.fontSizes.forEach(mark => {
             fontSizeBtns.push(this.dropdownFontSizeBtn(String(mark.attrs.fontSize), "color: black; width: 50px;", mark, this.view, this.changeToFontSize));
         });
 
-        let newfontSizeDom = (new Dropdown(fontSizeBtns, {
+        const newfontSizeDom = (new Dropdown(fontSizeBtns, {
             label: label,
             css: "color:black; min-width: 60px;"
         }) as MenuItem).render(this.view).dom;
@@ -312,12 +312,12 @@ export class TooltipTextMenu {
     //label of dropdown will change to given label
     updateFontStyleDropdown(label: string) {
         //font STYLES
-        let fontBtns: MenuItem[] = [];
+        const fontBtns: MenuItem[] = [];
         this.fontStyles.forEach((mark) => {
             fontBtns.push(this.dropdownFontFamilyBtn(mark.attrs.family, "color: black; font-family: " + mark.attrs.family + ", sans-serif; width: 125px;", mark, this.view, this.changeToFontFamily));
         });
 
-        let newfontStyleDom = (new Dropdown(fontBtns, {
+        const newfontStyleDom = (new Dropdown(fontBtns, {
             label: label,
             css: "color:black; width: 125px;"
         }) as MenuItem).render(this.view).dom;
@@ -339,19 +339,19 @@ export class TooltipTextMenu {
             this.linkText.style.overflow = "hidden";
             this.linkText.style.color = "white";
             this.linkText.onpointerdown = (e: PointerEvent) => { e.stopPropagation(); };
-            let linkBtn = document.createElement("div");
+            const linkBtn = document.createElement("div");
             linkBtn.textContent = ">>";
             linkBtn.style.width = "10px";
             linkBtn.style.height = "10px";
             linkBtn.style.color = "white";
             linkBtn.style.cssFloat = "left";
             linkBtn.onpointerdown = (e: PointerEvent) => {
-                let node = this.view.state.selection.$from.nodeAfter;
-                let link = node && node.marks.find(m => m.type.name === "link");
+                const node = this.view.state.selection.$from.nodeAfter;
+                const link = node && node.marks.find(m => m.type.name === "link");
                 if (link) {
-                    let href: string = link.attrs.href;
+                    const href: string = link.attrs.href;
                     if (href.indexOf(Utils.prepend("/doc/")) === 0) {
-                        let docid = href.replace(Utils.prepend("/doc/"), "");
+                        const docid = href.replace(Utils.prepend("/doc/"), "");
                         DocServer.GetRefField(docid).then(action((f: Opt<Field>) => {
                             if (f instanceof Doc) {
                                 if (DocumentManager.Instance.getDocumentView(f)) {
@@ -374,23 +374,23 @@ export class TooltipTextMenu {
             this.linkDrag.id = "link-drag";
             this.linkDrag.onpointerdown = (e: PointerEvent) => {
                 if (!this.editorProps) return;
-                let dragData = new DragManager.LinkDragData(this.editorProps.Document);
+                const dragData = new DragManager.LinkDragData(this.editorProps.Document);
                 dragData.dontClearTextBox = true;
                 // hack to get source context -sy
-                let docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document);
+                const docView = DocumentManager.Instance.getDocumentView(this.editorProps.Document);
                 e.stopPropagation();
-                let ctrlKey = e.ctrlKey;
+                const ctrlKey = e.ctrlKey;
                 DragManager.StartLinkDrag(this.linkDrag!, dragData, e.clientX, e.clientY,
                     {
                         handlers: {
                             dragComplete: action(() => {
                                 if (dragData.linkDocument) {
-                                    let linkDoc = dragData.linkDocument;
-                                    let proto = Doc.GetProto(linkDoc);
+                                    const linkDoc = dragData.linkDocument;
+                                    const proto = Doc.GetProto(linkDoc);
                                     if (proto && docView) {
                                         proto.sourceContext = docView.props.ContainingCollectionDoc;
                                     }
-                                    let text = this.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), ctrlKey ? "onRight" : "inTab");
+                                    const text = this.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), ctrlKey ? "onRight" : "inTab");
                                     if (linkDoc instanceof Doc && linkDoc.anchor2 instanceof Doc) {
                                         proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODODO open to more descriptive descriptions of following in text link
                                     }
@@ -406,8 +406,8 @@ export class TooltipTextMenu {
             this.tooltip.appendChild(this.linkEditor);
         }
 
-        let node = this.view.state.selection.$from.nodeAfter;
-        let link = node && node.marks.find(m => m.type.name === "link");
+        const node = this.view.state.selection.$from.nodeAfter;
+        const link = node && node.marks.find(m => m.type.name === "link");
         this.linkText.textContent = link ? link.attrs.href : "-empty-";
 
         this.linkText.onkeydown = (e: KeyboardEvent) => {
@@ -420,19 +420,19 @@ export class TooltipTextMenu {
     }
 
     async getTextLinkTargetTitle() {
-        let node = this.view.state.selection.$from.nodeAfter;
-        let link = node && node.marks.find(m => m.type.name === "link");
+        const node = this.view.state.selection.$from.nodeAfter;
+        const link = node && node.marks.find(m => m.type.name === "link");
         if (link) {
-            let href = link.attrs.href;
+            const href = link.attrs.href;
             if (href) {
                 if (href.indexOf(Utils.prepend("/doc/")) === 0) {
                     const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
                     if (linkclicked) {
-                        let linkDoc = await DocServer.GetRefField(linkclicked);
+                        const linkDoc = await DocServer.GetRefField(linkclicked);
                         if (linkDoc instanceof Doc) {
-                            let anchor1 = await Cast(linkDoc.anchor1, Doc);
-                            let anchor2 = await Cast(linkDoc.anchor2, Doc);
-                            let currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document;
+                            const anchor1 = await Cast(linkDoc.anchor1, Doc);
+                            const anchor2 = await Cast(linkDoc.anchor2, Doc);
+                            const currentDoc = SelectionManager.SelectedDocuments().length && SelectionManager.SelectedDocuments()[0].props.Document;
                             if (currentDoc && anchor1 && anchor2) {
                                 if (Doc.AreProtosEqual(currentDoc, anchor1)) {
                                     return StrCast(anchor2.title);
@@ -453,18 +453,18 @@ export class TooltipTextMenu {
     }
 
     async createLinkDropdown() {
-        let targetTitle = await this.getTextLinkTargetTitle();
-        let input = document.createElement("input");
+        const targetTitle = await this.getTextLinkTargetTitle();
+        const input = document.createElement("input");
 
         // menu item for input for hyperlink url 
         // TODO: integrate search to allow users to search for a doc to link to
-        let linkInfo = new MenuItem({
+        const linkInfo = new MenuItem({
             title: "",
             execEvent: "",
             class: "button-setting-disabled",
             css: "",
             render() {
-                let p = document.createElement("p");
+                const p = document.createElement("p");
                 p.textContent = "Linked to:";
 
                 input.type = "text";
@@ -475,7 +475,7 @@ export class TooltipTextMenu {
                     input.focus();
                 };
 
-                let div = document.createElement("div");
+                const div = document.createElement("div");
                 div.appendChild(p);
                 div.appendChild(input);
                 return div;
@@ -487,13 +487,13 @@ export class TooltipTextMenu {
         });
 
         // menu item to update/apply the hyperlink to the selected text
-        let linkApply = new MenuItem({
+        const linkApply = new MenuItem({
             title: "",
             execEvent: "",
             class: "",
             css: "",
             render() {
-                let button = document.createElement("button");
+                const button = document.createElement("button");
                 button.className = "link-url-button";
                 button.textContent = "Apply hyperlink";
                 return button;
@@ -507,17 +507,17 @@ export class TooltipTextMenu {
 
         // menu item to remove the link
         // TODO: allow this to be undoable
-        let self = this;
-        let deleteLink = new MenuItem({
+        const self = this;
+        const deleteLink = new MenuItem({
             title: "Delete link",
             execEvent: "",
             class: "separated-button",
             css: "",
             render() {
-                let button = document.createElement("button");
+                const button = document.createElement("button");
                 button.textContent = "Remove link";
 
-                let wrapper = document.createElement("div");
+                const wrapper = document.createElement("div");
                 wrapper.appendChild(button);
                 return wrapper;
             },
@@ -525,15 +525,15 @@ export class TooltipTextMenu {
             async run() {
                 self.deleteLink();
                 // update link dropdown
-                let dropdown = await self.createLinkDropdown();
-                let newLinkDropdowndom = dropdown.render(self.view).dom;
+                const dropdown = await self.createLinkDropdown();
+                const newLinkDropdowndom = dropdown.render(self.view).dom;
                 self._linkDropdownDom && self.tooltip.replaceChild(newLinkDropdowndom, self._linkDropdownDom);
                 self._linkDropdownDom = newLinkDropdowndom;
             }
         });
 
 
-        let linkDropdown = new Dropdown(targetTitle ? [linkInfo, linkApply, deleteLink] : [linkInfo, linkApply], { class: "buttonSettings-dropdown" }) as MenuItem;
+        const linkDropdown = new Dropdown(targetTitle ? [linkInfo, linkApply, deleteLink] : [linkInfo, linkApply], { class: "buttonSettings-dropdown" }) as MenuItem;
         return linkDropdown;
     }
 
@@ -542,10 +542,10 @@ export class TooltipTextMenu {
     // }
 
     makeLink = (targetDoc: Doc, title: string, location: string): string => {
-        let link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + targetDoc[Id]), title: title, location: location });
+        const link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + targetDoc[Id]), title: title, location: location });
         this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link).
             addMark(this.view.state.selection.from, this.view.state.selection.to, link));
-        let node = this.view.state.selection.$from.nodeAfter;
+        const node = this.view.state.selection.$from.nodeAfter;
         if (node && node.text) {
             return node.text;
         }
@@ -562,9 +562,9 @@ export class TooltipTextMenu {
     }
 
     deleteLink = () => {
-        let node = this.view.state.selection.$from.nodeAfter;
-        let link = node && node.marks.find(m => m.type === this.view.state.schema.marks.link);
-        let href = link!.attrs.href;
+        const node = this.view.state.selection.$from.nodeAfter;
+        const link = node && node.marks.find(m => m.type === this.view.state.schema.marks.link);
+        const href = link!.attrs.href;
         if (href) {
             if (href.indexOf(Utils.prepend("/doc/")) === 0) {
                 const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0];
@@ -599,7 +599,7 @@ export class TooltipTextMenu {
     }
 
     createLink() {
-        let markType = schema.marks.link;
+        const markType = schema.marks.link;
         return new MenuItem({
             title: "Add or remove link",
             label: "Add or remove link",
@@ -613,8 +613,8 @@ export class TooltipTextMenu {
                 let curLink = "";
                 if (this.markActive(state, markType)) {
 
-                    let { from, $from, to, empty } = state.selection;
-                    let node = state.doc.nodeAt(from);
+                    const { from, $from, to, empty } = state.selection;
+                    const node = state.doc.nodeAt(from);
                     node && node.marks.map(m => {
                         m.type === markType && (curLink = m.attrs.href);
                     });
@@ -649,7 +649,7 @@ export class TooltipTextMenu {
         if (listTypeBtn) { this.tooltip.removeChild(listTypeBtn); }
 
         //Make a dropdown of all list types
-        let toAdd: MenuItem[] = [];
+        const toAdd: MenuItem[] = [];
         this.listTypeToIcon.forEach((icon, type) => {
             toAdd.push(this.dropdownNodeBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeToNodeType));
         });
@@ -683,22 +683,22 @@ export class TooltipTextMenu {
 
     public static insertStar(state: EditorState<any>, dispatch: any) {
         if (state.selection.empty) return false;
-        let mark = state.schema.marks.highlight.create();
-        let tr = state.tr;
+        const mark = state.schema.marks.highlight.create();
+        const tr = state.tr;
         tr.addMark(state.selection.from, state.selection.to, mark);
-        let content = tr.selection.content();
-        let newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
+        const content = tr.selection.content();
+        const newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
         dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark));
         return true;
     }
 
     public static insertComment(state: EditorState<any>, dispatch: any) {
         if (state.selection.empty) return false;
-        let mark = state.schema.marks.highlight.create();
-        let tr = state.tr;
+        const mark = state.schema.marks.highlight.create();
+        const tr = state.tr;
         tr.addMark(state.selection.from, state.selection.to, mark);
-        let content = tr.selection.content();
-        let newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
+        const content = tr.selection.content();
+        const newNode = state.schema.nodes.star.create({ visibility: false, text: content, textslice: content.toJSON() });
         dispatch && dispatch(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark));
         return true;
     }
@@ -710,17 +710,17 @@ export class TooltipTextMenu {
             class: "menuicon",
             execEvent: "",
             render() {
-                let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                 svg.setAttribute("viewBox", "-100 -100 650 650");
-                let path = document.createElementNS('http://www.w3.org/2000/svg', "path");
+                const path = document.createElementNS('http://www.w3.org/2000/svg', "path");
                 path.setAttributeNS(null, "d", "M0 479.98L99.92 512l35.45-35.45-67.04-67.04L0 479.98zm124.61-240.01a36.592 36.592 0 0 0-10.79 38.1l13.05 42.83-50.93 50.94 96.23 96.23 50.86-50.86 42.74 13.08c13.73 4.2 28.65-.01 38.15-10.78l35.55-41.64-173.34-173.34-41.52 35.44zm403.31-160.7l-63.2-63.2c-20.49-20.49-53.38-21.52-75.12-2.35L190.55 183.68l169.77 169.78L530.27 154.4c19.18-21.74 18.15-54.63-2.35-75.13z");
                 svg.appendChild(path);
 
-                let color = document.createElement("div");
+                const color = document.createElement("div");
                 color.className = "buttonColor";
                 color.style.backgroundColor = TooltipTextMenuManager.Instance.highlight.toString();
 
-                let wrapper = document.createElement("div");
+                const wrapper = document.createElement("div");
                 wrapper.id = "colorPicker";
                 wrapper.appendChild(svg);
                 wrapper.appendChild(color);
@@ -735,26 +735,26 @@ export class TooltipTextMenu {
     public static insertHighlight(color: String, state: EditorState<any>, dispatch: any) {
         if (state.selection.empty) return false;
 
-        let highlightMark = state.schema.mark(state.schema.marks.marker, { highlight: color });
+        const highlightMark = state.schema.mark(state.schema.marks.marker, { highlight: color });
         dispatch(state.tr.addMark(state.selection.from, state.selection.to, highlightMark));
     }
 
     createHighlightDropdown() {
         // menu item for color picker
-        let self = this;
-        let colors = new MenuItem({
+        const self = this;
+        const colors = new MenuItem({
             title: "",
             execEvent: "",
             class: "button-setting-disabled",
             css: "",
             render() {
-                let p = document.createElement("p");
+                const p = document.createElement("p");
                 p.textContent = "Change highlight:";
 
-                let colorsWrapper = document.createElement("div");
+                const colorsWrapper = document.createElement("div");
                 colorsWrapper.className = "colorPicker-wrapper";
 
-                let colors = [
+                const colors = [
                     PastelSchemaPalette.get("pink2"),
                     PastelSchemaPalette.get("purple4"),
                     PastelSchemaPalette.get("bluegreen1"),
@@ -768,7 +768,7 @@ export class TooltipTextMenu {
                 ];
 
                 colors.forEach(color => {
-                    let button = document.createElement("button");
+                    const button = document.createElement("button");
                     button.className = color === TooltipTextMenuManager.Instance.highlight ? "colorPicker active" : "colorPicker";
                     if (color) {
                         button.style.backgroundColor = color;
@@ -779,8 +779,8 @@ export class TooltipTextMenu {
                             TooltipTextMenu.insertHighlight(TooltipTextMenuManager.Instance.highlight, self.view.state, self.view.dispatch);
 
                             // update color menu
-                            let highlightDom = self.createHighlightTool().render(self.view).dom;
-                            let highlightDropdownDom = self.createHighlightDropdown().render(self.view).dom;
+                            const highlightDom = self.createHighlightTool().render(self.view).dom;
+                            const highlightDropdownDom = self.createHighlightDropdown().render(self.view).dom;
                             self.highlightDom && self.tooltip.replaceChild(highlightDom, self.highlightDom);
                             self.highlightDropdownDom && self.tooltip.replaceChild(highlightDropdownDom, self.highlightDropdownDom);
                             self.highlightDom = highlightDom;
@@ -790,7 +790,7 @@ export class TooltipTextMenu {
                     colorsWrapper.appendChild(button);
                 });
 
-                let div = document.createElement("div");
+                const div = document.createElement("div");
                 div.appendChild(p);
                 div.appendChild(colorsWrapper);
                 return div;
@@ -801,7 +801,7 @@ export class TooltipTextMenu {
             }
         });
 
-        let colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
+        const colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
         return colorDropdown;
     }
 
@@ -812,17 +812,17 @@ export class TooltipTextMenu {
             class: "menuicon",
             execEvent: "",
             render() {
-                let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+                const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
                 svg.setAttribute("viewBox", "-100 -100 650 650");
-                let path = document.createElementNS('http://www.w3.org/2000/svg', "path");
+                const path = document.createElementNS('http://www.w3.org/2000/svg', "path");
                 path.setAttributeNS(null, "d", "M204.3 5C104.9 24.4 24.8 104.3 5.2 203.4c-37 187 131.7 326.4 258.8 306.7 41.2-6.4 61.4-54.6 42.5-91.7-23.1-45.4 9.9-98.4 60.9-98.4h79.7c35.8 0 64.8-29.6 64.9-65.3C511.5 97.1 368.1-26.9 204.3 5zM96 320c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm32-128c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128-64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32zm128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32 32 14.3 32 32-14.3 32-32 32z");
                 svg.appendChild(path);
 
-                let color = document.createElement("div");
+                const color = document.createElement("div");
                 color.className = "buttonColor";
                 color.style.backgroundColor = TooltipTextMenuManager.Instance.color.toString();
 
-                let wrapper = document.createElement("div");
+                const wrapper = document.createElement("div");
                 wrapper.id = "colorPicker";
                 wrapper.appendChild(svg);
                 wrapper.appendChild(color);
@@ -837,26 +837,26 @@ export class TooltipTextMenu {
     public static insertColor(color: String, state: EditorState<any>, dispatch: any) {
         if (state.selection.empty) return false;
 
-        let colorMark = state.schema.mark(state.schema.marks.color, { color: color });
+        const colorMark = state.schema.mark(state.schema.marks.color, { color: color });
         dispatch(state.tr.addMark(state.selection.from, state.selection.to, colorMark));
     }
 
     createColorDropdown() {
         // menu item for color picker
-        let self = this;
-        let colors = new MenuItem({
+        const self = this;
+        const colors = new MenuItem({
             title: "",
             execEvent: "",
             class: "button-setting-disabled",
             css: "",
             render() {
-                let p = document.createElement("p");
+                const p = document.createElement("p");
                 p.textContent = "Change color:";
 
-                let colorsWrapper = document.createElement("div");
+                const colorsWrapper = document.createElement("div");
                 colorsWrapper.className = "colorPicker-wrapper";
 
-                let colors = [
+                const colors = [
                     DarkPastelSchemaPalette.get("pink2"),
                     DarkPastelSchemaPalette.get("purple4"),
                     DarkPastelSchemaPalette.get("bluegreen1"),
@@ -870,7 +870,7 @@ export class TooltipTextMenu {
                 ];
 
                 colors.forEach(color => {
-                    let button = document.createElement("button");
+                    const button = document.createElement("button");
                     button.className = color === TooltipTextMenuManager.Instance.color ? "colorPicker active" : "colorPicker";
                     if (color) {
                         button.style.backgroundColor = color;
@@ -880,8 +880,8 @@ export class TooltipTextMenu {
                             TooltipTextMenu.insertColor(TooltipTextMenuManager.Instance.color, self.view.state, self.view.dispatch);
 
                             // update color menu
-                            let colorDom = self.createColorTool().render(self.view).dom;
-                            let colorDropdownDom = self.createColorDropdown().render(self.view).dom;
+                            const colorDom = self.createColorTool().render(self.view).dom;
+                            const colorDropdownDom = self.createColorDropdown().render(self.view).dom;
                             self.colorDom && self.tooltip.replaceChild(colorDom, self.colorDom);
                             self.colorDropdownDom && self.tooltip.replaceChild(colorDropdownDom, self.colorDropdownDom);
                             self.colorDom = colorDom;
@@ -891,7 +891,7 @@ export class TooltipTextMenu {
                     colorsWrapper.appendChild(button);
                 });
 
-                let div = document.createElement("div");
+                const div = document.createElement("div");
                 div.appendChild(p);
                 div.appendChild(colorsWrapper);
                 return div;
@@ -902,7 +902,7 @@ export class TooltipTextMenu {
             }
         });
 
-        let colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
+        const colorDropdown = new Dropdown([colors], { class: "buttonSettings-dropdown" }) as MenuItem;
         return colorDropdown;
     }
 
@@ -911,7 +911,7 @@ export class TooltipTextMenu {
             height: 32, width: 32,
             path: "M30.828 1.172c-1.562-1.562-4.095-1.562-5.657 0l-5.379 5.379-3.793-3.793-4.243 4.243 3.326 3.326-14.754 14.754c-0.252 0.252-0.358 0.592-0.322 0.921h-0.008v5c0 0.552 0.448 1 1 1h5c0 0 0.083 0 0.125 0 0.288 0 0.576-0.11 0.795-0.329l14.754-14.754 3.326 3.326 4.243-4.243-3.793-3.793 5.379-5.379c1.562-1.562 1.562-4.095 0-5.657zM5.409 30h-3.409v-3.409l14.674-14.674 3.409 3.409-14.674 14.674z"
         };
-        let self = this;
+        const self = this;
         return new MenuItem({
             title: "Brush tool",
             label: "Brush tool",
@@ -923,7 +923,7 @@ export class TooltipTextMenu {
                 this.brush_function(state, dispatch);
 
                 // update dropdown with marks
-                let newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom;
+                const newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom;
                 self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom);
                 self._brushDropdownDom = newBrushDropdowndom;
             },
@@ -947,7 +947,7 @@ export class TooltipTextMenu {
             }
         }
         else {
-            let { from, to, $from } = this.view.state.selection;
+            const { from, to, $from } = this.view.state.selection;
             if (this._brushdom) {
                 if (!this.view.state.selection.empty && $from && $from.nodeAfter) {
                     if (TooltipTextMenuManager.Instance._brushMarks && to - from > 0) {
@@ -982,7 +982,7 @@ export class TooltipTextMenu {
         }
 
 
-        let brushInfo = new MenuItem({
+        const brushInfo = new MenuItem({
             title: "",
             label: label,
             execEvent: "",
@@ -994,17 +994,17 @@ export class TooltipTextMenu {
             }
         });
 
-        let self = this;
-        let clearBrush = new MenuItem({
+        const self = this;
+        const clearBrush = new MenuItem({
             title: "Clear brush",
             execEvent: "",
             class: "separated-button",
             css: "",
             render() {
-                let button = document.createElement("button");
+                const button = document.createElement("button");
                 button.textContent = "Clear brush";
 
-                let wrapper = document.createElement("div");
+                const wrapper = document.createElement("div");
                 wrapper.appendChild(button);
                 return wrapper;
             },
@@ -1015,24 +1015,24 @@ export class TooltipTextMenu {
 
                 // update brush tool
                 // TODO: this probably isn't very clean
-                let newBrushdom = self.createBrush().render(self.view).dom;
+                const newBrushdom = self.createBrush().render(self.view).dom;
                 self._brushdom && self.tooltip.replaceChild(newBrushdom, self._brushdom);
                 self._brushdom = newBrushdom;
-                let newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom;
+                const newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom;
                 self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom);
                 self._brushDropdownDom = newBrushDropdowndom;
             }
         });
 
-        let hasMarks = TooltipTextMenuManager.Instance._brushMarks && TooltipTextMenuManager.Instance._brushMarks.size > 0;
-        let brushDom = new Dropdown(hasMarks ? [brushInfo, clearBrush] : [brushInfo], { class: "buttonSettings-dropdown" }) as MenuItem;
+        const hasMarks = TooltipTextMenuManager.Instance._brushMarks && TooltipTextMenuManager.Instance._brushMarks.size > 0;
+        const brushDom = new Dropdown(hasMarks ? [brushInfo, clearBrush] : [brushInfo], { class: "buttonSettings-dropdown" }) as MenuItem;
         return brushDom;
     }
     //for a specific grouping of marks (passed in), remove all and apply the passed-in one to the selected textchangeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => {
     changeToMarkInGroup = (markType: MarkType | undefined, view: EditorView, fontMarks: MarkType[]) => {
-        let { $cursor, ranges } = view.state.selection as TextSelection;
-        let state = view.state;
-        let dispatch = view.dispatch;
+        const { $cursor, ranges } = view.state.selection as TextSelection;
+        const state = view.state;
+        const dispatch = view.dispatch;
 
         //remove all other active font marks
         fontMarks.forEach((type) => {
@@ -1044,10 +1044,10 @@ export class TooltipTextMenu {
                 } else {
                     let has = false;
                     for (let i = 0; !has && i < ranges.length; i++) {
-                        let { $from, $to } = ranges[i];
+                        const { $from, $to } = ranges[i];
                         has = state.doc.rangeHasMark($from.pos, $to.pos, type);
                     }
-                    for (let i of ranges) {
+                    for (const i of ranges) {
                         if (has) {
                             toggleMark(type)(view.state, view.dispatch, view);
                         }
@@ -1059,7 +1059,7 @@ export class TooltipTextMenu {
         if (markType) {
             //actually apply font
             if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) {
-                let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
+                const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
                     { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: markType.name, setFontSize: Number(markType.name.replace(/p/, "")) }), view.state.schema);
                 view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from))));
             }
@@ -1068,9 +1068,9 @@ export class TooltipTextMenu {
     }
 
     changeToFontFamily = (mark: Mark, view: EditorView) => {
-        let { $cursor, ranges } = view.state.selection as TextSelection;
-        let state = view.state;
-        let dispatch = view.dispatch;
+        const { $cursor, ranges } = view.state.selection as TextSelection;
+        const state = view.state;
+        const dispatch = view.dispatch;
 
         //remove all other active font marks
         if ($cursor) {
@@ -1080,28 +1080,28 @@ export class TooltipTextMenu {
         } else {
             let has = false;
             for (let i = 0; !has && i < ranges.length; i++) {
-                let { $from, $to } = ranges[i];
+                const { $from, $to } = ranges[i];
                 has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontFamily);
             }
-            for (let i of ranges) {
+            for (const i of ranges) {
                 if (has) {
                     toggleMark(view.state.schema.marks.pFontFamily)(view.state, view.dispatch, view);
                 }
             }
         }
 
-        let fontName = mark.attrs.family;
+        const fontName = mark.attrs.family;
         if (fontName) { this.updateFontStyleDropdown(fontName); }
         if (this.editorProps) {
-            let ruleProvider = this.editorProps.ruleProvider;
-            let heading = NumCast(this.editorProps.Document.heading);
+            const ruleProvider = this.editorProps.ruleProvider;
+            const heading = NumCast(this.editorProps.Document.heading);
             if (ruleProvider && heading) {
                 ruleProvider["ruleFont_" + heading] = fontName;
             }
         }
         //actually apply font
         if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) {
-            let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
+            const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
                 { ...(view.state.selection as NodeSelection).node.attrs, setFontFamily: fontName }), view.state.schema);
             view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from))));
         }
@@ -1110,9 +1110,9 @@ export class TooltipTextMenu {
     }
 
     changeToFontSize = (mark: Mark, view: EditorView) => {
-        let { $cursor, ranges } = view.state.selection as TextSelection;
-        let state = view.state;
-        let dispatch = view.dispatch;
+        const { $cursor, ranges } = view.state.selection as TextSelection;
+        const state = view.state;
+        const dispatch = view.dispatch;
 
         //remove all other active font marks
         if ($cursor) {
@@ -1122,28 +1122,28 @@ export class TooltipTextMenu {
         } else {
             let has = false;
             for (let i = 0; !has && i < ranges.length; i++) {
-                let { $from, $to } = ranges[i];
+                const { $from, $to } = ranges[i];
                 has = state.doc.rangeHasMark($from.pos, $to.pos, view.state.schema.marks.pFontSize);
             }
-            for (let i of ranges) {
+            for (const i of ranges) {
                 if (has) {
                     toggleMark(view.state.schema.marks.pFontSize)(view.state, view.dispatch, view);
                 }
             }
         }
 
-        let size = mark.attrs.fontSize;
+        const size = mark.attrs.fontSize;
         if (size) { this.updateFontSizeDropdown(String(size) + " pt"); }
         if (this.editorProps) {
-            let ruleProvider = this.editorProps.ruleProvider;
-            let heading = NumCast(this.editorProps.Document.heading);
+            const ruleProvider = this.editorProps.ruleProvider;
+            const heading = NumCast(this.editorProps.Document.heading);
             if (ruleProvider && heading) {
                 ruleProvider["ruleSize_" + heading] = size;
             }
         }
         //actually apply font
         if ((view.state.selection as any).node && (view.state.selection as any).node.type === view.state.schema.nodes.ordered_list) {
-            let status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
+            const status = updateBullets(view.state.tr.setNodeMarkup(view.state.selection.from, (view.state.selection as any).node.type,
                 { ...(view.state.selection as NodeSelection).node.attrs, setFontSize: size }), view.state.schema);
             view.dispatch(status.setSelection(new NodeSelection(status.doc.resolve(view.state.selection.from))));
         }
@@ -1154,20 +1154,20 @@ export class TooltipTextMenu {
     //remove all node typeand apply the passed-in one to the selected text
     changeToNodeType = (nodeType: NodeType | undefined) => {
         //remove oldif (nodeType) { //add new
-        let view = this.view;
+        const view = this.view;
         if (nodeType === schema.nodes.bullet_list) {
             wrapInList(nodeType)(view.state, view.dispatch);
         } else {
-            var marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks());
+            const marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks());
             if (!wrapInList(schema.nodes.ordered_list)(view.state, (tx2: any) => {
-                let tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle);
+                const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle);
                 marks && tx3.ensureMarks([...marks]);
                 marks && tx3.setStoredMarks([...marks]);
 
                 view.dispatch(tx2);
             })) {
-                let tx2 = view.state.tr;
-                let tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle);
+                const tx2 = view.state.tr;
+                const tx3 = updateBullets(tx2, schema, nodeType && (nodeType as any).attrs.mapStyle);
                 marks && tx3.ensureMarks([...marks]);
                 marks && tx3.setStoredMarks([...marks]);
 
@@ -1223,15 +1223,15 @@ export class TooltipTextMenu {
         });
     }
 
-    markActive = function(state: EditorState<any>, type: MarkType<Schema<string, string>>) {
-        let { from, $from, to, empty } = state.selection;
+    markActive = function (state: EditorState<any>, type: MarkType<Schema<string, string>>) {
+        const { from, $from, to, empty } = state.selection;
         if (empty) return type.isInSet(state.storedMarks || $from.marks());
         else return state.doc.rangeHasMark(from, to, type);
     };
 
     // Helper function to create menu icons
     icon(text: string, name: string, title: string = name) {
-        let span = document.createElement("span");
+        const span = document.createElement("span");
         span.className = name + " menuicon";
         span.title = title;
         span.textContent = text;
@@ -1240,13 +1240,13 @@ export class TooltipTextMenu {
     }
 
     svgIcon(name: string, title: string = name, dpath: string) {
-        let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+        const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
         svg.setAttribute("viewBox", "-100 -100 650 650");
-        let path = document.createElementNS('http://www.w3.org/2000/svg', "path");
+        const path = document.createElementNS('http://www.w3.org/2000/svg', "path");
         path.setAttributeNS(null, "d", dpath);
         svg.appendChild(path);
 
-        let span = document.createElement("span");
+        const span = document.createElement("span");
         span.className = name + " menuicon";
         span.title = title;
         span.appendChild(svg);
@@ -1256,9 +1256,9 @@ export class TooltipTextMenu {
 
     //method for checking whether node can be inserted
     canInsert(state: EditorState, nodeType: NodeType<Schema<string, string>>) {
-        let $from = state.selection.$from;
+        const $from = state.selection.$from;
         for (let d = $from.depth; d >= 0; d--) {
-            let index = $from.index(d);
+            const index = $from.index(d);
             if ($from.node(d).canReplaceWith(index, index, nodeType)) return true;
         }
         return false;
@@ -1267,13 +1267,13 @@ export class TooltipTextMenu {
 
     //adapted this method - use it to check if block has a tag (ie bulleting)
     blockActive(type: NodeType<Schema<string, string>>, state: EditorState) {
-        let attrs = {};
+        const attrs = {};
 
         if (state.selection instanceof NodeSelection) {
             const sel: NodeSelection = state.selection;
-            let $from = sel.$from;
-            let to = sel.to;
-            let node = sel.node;
+            const $from = sel.$from;
+            const to = sel.to;
+            const node = sel.node;
 
             if (node) {
                 return node.hasMarkup(type, attrs);
@@ -1292,10 +1292,10 @@ export class TooltipTextMenu {
     }
 
     getMarksInSelection(state: EditorState<any>) {
-        let found = new Set<Mark>();
-        let { from, to } = state.selection as TextSelection;
+        const found = new Set<Mark>();
+        const { from, to } = state.selection as TextSelection;
         state.doc.nodesBetween(from, to, (node) => {
-            let marks = node.marks;
+            const marks = node.marks;
             if (marks) {
                 marks.forEach(m => {
                     found.add(m);
@@ -1306,7 +1306,7 @@ export class TooltipTextMenu {
     }
 
     reset_mark_doms() {
-        let iterator = this._marksToDoms.values();
+        const iterator = this._marksToDoms.values();
         let next = iterator.next();
         while (!next.done) {
             next.value.style.color = "white";
@@ -1322,7 +1322,7 @@ export class TooltipTextMenu {
             return;
         }
         this.view = view;
-        let state = view.state;
+        const state = view.state;
         DocumentDecorations.Instance.showTextBar();
         props && (this.editorProps = props);
         // Don't do anything if the document/selection didn't change
@@ -1338,13 +1338,13 @@ export class TooltipTextMenu {
         }
 
         // update link dropdown
-        let linkDropdown = await this.createLinkDropdown();
-        let newLinkDropdowndom = linkDropdown.render(this.view).dom;
+        const linkDropdown = await this.createLinkDropdown();
+        const newLinkDropdowndom = linkDropdown.render(this.view).dom;
         this._linkDropdownDom && this.tooltip.replaceChild(newLinkDropdowndom, this._linkDropdownDom);
         this._linkDropdownDom = newLinkDropdowndom;
 
         //UPDATE FONT STYLE DROPDOWN
-        let activeStyles = this.activeFontFamilyOnSelection();
+        const activeStyles = this.activeFontFamilyOnSelection();
         if (activeStyles !== undefined) {
             if (activeStyles.length === 1) {
                 console.log("updating font style dropdown", activeStyles[0]);
@@ -1353,7 +1353,7 @@ export class TooltipTextMenu {
         }
 
         //UPDATE FONT SIZE DROPDOWN
-        let activeSizes = this.activeFontSizeOnSelection();
+        const activeSizes = this.activeFontSizeOnSelection();
         if (activeSizes !== undefined) {
             if (activeSizes.length === 1) { //if there's only one active font size
                 activeSizes[0] && this.updateFontSizeDropdown(String(activeSizes[0]) + " pt");
@@ -1366,7 +1366,7 @@ export class TooltipTextMenu {
         this.reset_mark_doms();
         this._activeMarks.forEach((mark) => {
             if (this._marksToDoms.has(mark)) {
-                let dom = this._marksToDoms.get(mark);
+                const dom = this._marksToDoms.get(mark);
                 if (dom) dom.style.color = "greenyellow";
             }
         });
@@ -1385,8 +1385,8 @@ export class TooltipTextMenu {
     //finds fontSize at start of selection
     activeFontSizeOnSelection() {
         //current selection
-        let state = this.view.state;
-        let activeSizes: number[] = [];
+        const state = this.view.state;
+        const activeSizes: number[] = [];
         const pos = this.view.state.selection.$from;
         const ref_node: ProsNode = this.reference_node(pos);
         if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
@@ -1397,8 +1397,8 @@ export class TooltipTextMenu {
     //finds fontSize at start of selection
     activeFontFamilyOnSelection() {
         //current selection
-        let state = this.view.state;
-        let activeFamilies: string[] = [];
+        const state = this.view.state;
+        const activeFamilies: string[] = [];
         const pos = this.view.state.selection.$from;
         const ref_node: ProsNode = this.reference_node(pos);
         if (ref_node && ref_node !== this.view.state.doc && ref_node.isText) {
@@ -1409,15 +1409,15 @@ export class TooltipTextMenu {
     //finds all active marks on selection in given group
     activeMarksOnSelection(markGroup: MarkType[]) {
         //current selection
-        let { empty, ranges, $to } = this.view.state.selection as TextSelection;
-        let state = this.view.state;
-        let dispatch = this.view.dispatch;
+        const { empty, ranges, $to } = this.view.state.selection as TextSelection;
+        const state = this.view.state;
+        const dispatch = this.view.dispatch;
         let activeMarks: MarkType[];
         if (!empty) {
             activeMarks = markGroup.filter(mark => {
-                let has = false;
+                const has = false;
                 for (let i = 0; !has && i < ranges.length; i++) {
-                    let { $from, $to } = ranges[i];
+                    const { $from, $to } = ranges[i];
                     return state.doc.rangeHasMark($from.pos, $to.pos, mark);
                 }
                 return false;
@@ -1440,7 +1440,7 @@ export class TooltipTextMenu {
                     if (mark_type === state.schema.marks.pFontSize) {
                         return ref_node.marks.some(m => m.type.name === state.schema.marks.pFontSize.name);
                     }
-                    let mark = state.schema.mark(mark_type);
+                    const mark = state.schema.mark(mark_type);
                     return ref_node.marks.includes(mark);
                     return false;
                 });
diff --git a/src/client/util/TypedEvent.ts b/src/client/util/TypedEvent.ts
index 532ba78eb..90fd299c1 100644
--- a/src/client/util/TypedEvent.ts
+++ b/src/client/util/TypedEvent.ts
@@ -1,40 +1,40 @@
 export interface Listener<T> {
-  (event: T): any;
+    (event: T): any;
 }
 
 export interface Disposable {
-  dispose(): void;
+    dispose(): void;
 }
 
 /** passes through events as they happen. You will not get events from before you start listening */
 export class TypedEvent<T> {
-  private listeners: Listener<T>[] = [];
-  private listenersOncer: Listener<T>[] = [];
-
-  on = (listener: Listener<T>): Disposable => {
-    this.listeners.push(listener);
-    return {
-      dispose: () => this.off(listener)
-    };
-  }
-
-  once = (listener: Listener<T>): void => {
-    this.listenersOncer.push(listener);
-  }
-
-  off = (listener: Listener<T>) => {
-    var callbackIndex = this.listeners.indexOf(listener);
-    if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
-  }
-
-  emit = (event: T) => {
-    /** Update any general listeners */
-    this.listeners.forEach((listener) => listener(event));
-
-    /** Clear the `once` queue */
-    this.listenersOncer.forEach((listener) => listener(event));
-    this.listenersOncer = [];
-  }
-
-  pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e));
+    private listeners: Listener<T>[] = [];
+    private listenersOncer: Listener<T>[] = [];
+
+    on = (listener: Listener<T>): Disposable => {
+        this.listeners.push(listener);
+        return {
+            dispose: () => this.off(listener)
+        };
+    }
+
+    once = (listener: Listener<T>): void => {
+        this.listenersOncer.push(listener);
+    }
+
+    off = (listener: Listener<T>) => {
+        const callbackIndex = this.listeners.indexOf(listener);
+        if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
+    }
+
+    emit = (event: T) => {
+        /** Update any general listeners */
+        this.listeners.forEach((listener) => listener(event));
+
+        /** Clear the `once` queue */
+        this.listenersOncer.forEach((listener) => listener(event));
+        this.listenersOncer = [];
+    }
+
+    pipe = (te: TypedEvent<T>): Disposable => this.on((e) => te.emit(e));
 }
\ No newline at end of file
diff --git a/src/client/util/UndoManager.ts b/src/client/util/UndoManager.ts
index 472afac1d..314b52bf3 100644
--- a/src/client/util/UndoManager.ts
+++ b/src/client/util/UndoManager.ts
@@ -3,7 +3,7 @@ import 'source-map-support/register';
 import { Without } from "../../Utils";
 
 function getBatchName(target: any, key: string | symbol): string {
-    let keyName = key.toString();
+    const keyName = key.toString();
     if (target && target.constructor && target.constructor.name) {
         return `${target.constructor.name}.${keyName}`;
     }
@@ -23,7 +23,7 @@ function propertyDecorator(target: any, key: string | symbol) {
                 writable: true,
                 configurable: true,
                 value: function (...args: any[]) {
-                    let batch = UndoManager.StartBatch(getBatchName(target, key));
+                    const batch = UndoManager.StartBatch(getBatchName(target, key));
                     try {
                         return value.apply(this, args);
                     } finally {
@@ -40,7 +40,7 @@ export function undoBatch(fn: (...args: any[]) => any): (...args: any[]) => any;
 export function undoBatch(target: any, key?: string | symbol, descriptor?: TypedPropertyDescriptor<any>): any {
     if (!key) {
         return function () {
-            let batch = UndoManager.StartBatch("");
+            const batch = UndoManager.StartBatch("");
             try {
                 return target.apply(undefined, arguments);
             } finally {
@@ -55,7 +55,7 @@ export function undoBatch(target: any, key?: string | symbol, descriptor?: Typed
     const oldFunction = descriptor.value;
 
     descriptor.value = function (...args: any[]) {
-        let batch = UndoManager.StartBatch(getBatchName(target, key));
+        const batch = UndoManager.StartBatch(getBatchName(target, key));
         try {
             return oldFunction.apply(this, args);
         } finally {
@@ -98,7 +98,7 @@ export namespace UndoManager {
         GetOpenBatches().forEach(batch => console.log(batch.batchName));
     }
 
-    let openBatches: Batch[] = [];
+    const openBatches: Batch[] = [];
     export function GetOpenBatches(): Without<Batch, 'end'>[] {
         return openBatches;
     }
@@ -146,7 +146,7 @@ export namespace UndoManager {
 
     //TODO Make this return the return value
     export function RunInBatch<T>(fn: () => T, batchName: string) {
-        let batch = StartBatch(batchName);
+        const batch = StartBatch(batchName);
         try {
             return runInAction(fn);
         } finally {
@@ -159,7 +159,7 @@ export namespace UndoManager {
             return;
         }
 
-        let commands = undoStack.pop();
+        const commands = undoStack.pop();
         if (!commands) {
             return;
         }
@@ -178,7 +178,7 @@ export namespace UndoManager {
             return;
         }
 
-        let commands = redoStack.pop();
+        const commands = redoStack.pop();
         if (!commands) {
             return;
         }
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index f718735a8..09e4ef99c 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -48,12 +48,12 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
     dimension = () => NumCast(this.props.Document.height); // 2 * the padding
     getTransform = (ele: React.RefObject<HTMLDivElement>) => () => {
         if (!ele.current) return Transform.Identity();
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current);
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current);
         return new Transform(-translateX, -translateY, 1 / scale);
     }
 
     render() {
-        let guid = Utils.GenerateGuid();
+        const guid = Utils.GenerateGuid();
         return <div className="collectionLinearView-outer">
             <div className="collectionLinearView" ref={this.createDropTarget} >
                 <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
@@ -62,10 +62,10 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
                 <div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document.width, 25) }}>
                     {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => {
-                        let nested = pair.layout.viewType === CollectionViewType.Linear;
-                        let dref = React.createRef<HTMLDivElement>();
-                        let nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension());
-                        let deltaSize = nativeWidth * .15 / 2;
+                        const nested = pair.layout.viewType === CollectionViewType.Linear;
+                        const dref = React.createRef<HTMLDivElement>();
+                        const nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension());
+                        const deltaSize = nativeWidth * .15 / 2;
                         return <div className={`collectionLinearView-docBtn` + (pair.layout.onClick || pair.layout.onDragStart ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
                             style={{
                                 width: nested ? pair.layout[WidthSym]() : this.dimension() - deltaSize,
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 5d452e72e..937aff0d6 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -49,8 +49,8 @@ export class ContextMenu extends React.Component {
     @action
     onPointerUp = (e: PointerEvent) => {
         this._mouseDown = false;
-        let curX = e.clientX;
-        let curY = e.clientY;
+        const curX = e.clientX;
+        const curY = e.clientY;
         if (this._mouseX !== curX || this._mouseY !== curY) {
             this._shouldDisplay = false;
         }
@@ -208,7 +208,7 @@ export class ContextMenu extends React.Component {
         if (!this._display) {
             return null;
         }
-        let style = this._yRelativeToTop ? { left: this.pageX, top: this.pageY } :
+        const style = this._yRelativeToTop ? { left: this.pageX, top: this.pageY } :
             { left: this.pageX, bottom: this.pageY };
 
         const contents = (
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 330b94afa..fef9e5f60 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -88,7 +88,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
                 </div>
             );
         } else if ("subitems" in this.props) {
-            let submenu = !this.overItem ? (null) :
+            const submenu = !this.overItem ? (null) :
                 <div className="contextMenu-subMenu-cont" style={{ marginLeft: "25%", left: "0px" }}>
                     {this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />)}
                 </div>;
diff --git a/src/client/views/DictationOverlay.tsx b/src/client/views/DictationOverlay.tsx
index 2accf9bfd..65770c0bb 100644
--- a/src/client/views/DictationOverlay.tsx
+++ b/src/client/views/DictationOverlay.tsx
@@ -24,7 +24,7 @@ export class DictationOverlay extends React.Component {
     }
 
     public initiateDictationFade = () => {
-        let duration = DictationManager.Commands.dictationFadeDuration;
+        const duration = DictationManager.Commands.dictationFadeDuration;
         this.overlayTimeout = setTimeout(() => {
             this.dictationOverlayVisible = false;
             this.dictationSuccess = undefined;
@@ -50,14 +50,14 @@ export class DictationOverlay extends React.Component {
     public set isListening(value: DictationManager.Controls.ListeningUIStatus) { runInAction(() => this._dictationListeningState = value); }
 
     render() {
-        let success = this.dictationSuccess;
-        let result = this.isListening && !this.isListening.interim ? DictationManager.placeholder : `"${this.dictatedPhrase}"`;
-        let dialogueBoxStyle = {
+        const success = this.dictationSuccess;
+        const result = this.isListening && !this.isListening.interim ? DictationManager.placeholder : `"${this.dictatedPhrase}"`;
+        const dialogueBoxStyle = {
             background: success === undefined ? "gainsboro" : success ? "lawngreen" : "red",
             borderColor: this.isListening ? "red" : "black",
             fontStyle: "italic"
         };
-        let overlayStyle = {
+        const overlayStyle = {
             backgroundColor: this.isListening ? "red" : "darkslategrey"
         };
         return (<MainViewModal
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index b3a130b33..27ee9f122 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,4 +1,3 @@
-import * as React from 'react';
 import { Doc } from '../../new_fields/Doc';
 import { Touchable } from './Touchable';
 import { computed, action, observable } from 'mobx';
@@ -65,8 +64,8 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         @action.bound
         removeDocument(doc: Doc): boolean {
             Doc.GetProto(doc).annotationOn = undefined;
-            let value = this.extensionDoc && Cast(this.extensionDoc[this.annotationsKey], listSpec(Doc), []);
-            let index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1;
+            const value = this.extensionDoc && Cast(this.extensionDoc[this.annotationsKey], listSpec(Doc), []);
+            const index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1;
             return index !== -1 && value && value.splice(index, 1) ? true : false;
         }
         // if the moved document is already in this overlay collection nothing needs to be done.
diff --git a/src/client/views/DocumentButtonBar.scss b/src/client/views/DocumentButtonBar.scss
index db6bf2ba0..c2ca93900 100644
--- a/src/client/views/DocumentButtonBar.scss
+++ b/src/client/views/DocumentButtonBar.scss
@@ -17,6 +17,7 @@ $linkGap : 3px;
     transform: scale(1.05);
     cursor: pointer;
 }
+
 .documentButtonBar-linkButton-empty,
 .documentButtonBar-linkButton-nonempty {
     height: 20px;
@@ -74,6 +75,31 @@ $linkGap : 3px;
 }
 
 
-@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
-@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
-@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }
\ No newline at end of file
+@-moz-keyframes spin {
+    100% {
+        -moz-transform: rotate(360deg);
+    }
+}
+
+@-webkit-keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+    }
+}
+
+@keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+        transform: rotate(360deg);
+    }
+}
+
+@keyframes shadow-pulse {
+    0% {
+        box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.8);
+    }
+
+    100% {
+        box-shadow: 0 0 0 10px rgba(0, 255, 0, 0);
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 1fefc70f1..15cbd2788 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -21,6 +21,7 @@ import React = require("react");
 import { DocumentView } from './nodes/DocumentView';
 import { ParentDocSelector } from './collections/ParentDocumentSelector';
 import { CollectionDockingView } from './collections/CollectionDockingView';
+import { DocumentDecorations } from './DocumentDecorations';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -51,7 +52,9 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
     @observable private pushIcon: IconProp = "arrow-alt-circle-up";
     @observable private pullIcon: IconProp = "arrow-alt-circle-down";
     @observable private pullColor: string = "white";
-    @observable private isAnimatingFetch = false;
+    @observable public isAnimatingFetch = false;
+    @observable public isAnimatingPulse = false;
+
     @observable private openHover = false;
 
     public static Instance: DocumentButtonBar;
@@ -75,6 +78,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
     });
 
     public startPushOutcome = action((success: boolean) => {
+        this.isAnimatingPulse = false;
         if (!this._pushAnimating) {
             this._pushAnimating = true;
             this.pushIcon = success ? "check-circle" : "stop-circle";
@@ -99,27 +103,26 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
         this._pullColorAnimating = false;
     });
 
-
     @action
     onLinkButtonMoved = (e: PointerEvent): void => {
         if (this._linkButton.current !== null && (Math.abs(e.clientX - this._downX) > 3 || Math.abs(e.clientY - this._downY) > 3)) {
             document.removeEventListener("pointermove", this.onLinkButtonMoved);
             document.removeEventListener("pointerup", this.onLinkButtonUp);
-            let docView = this.props.views[0];
-            let container = docView.props.ContainingCollectionDoc?.proto;
-            let dragData = new DragManager.LinkDragData(docView.props.Document, container ? [container] : []);
-            let linkDrag = UndoManager.StartBatch("Drag Link");
+            const docView = this.props.views[0];
+            const container = docView.props.ContainingCollectionDoc?.proto;
+            const dragData = new DragManager.LinkDragData(docView.props.Document, container ? [container] : []);
+            const linkDrag = UndoManager.StartBatch("Drag Link");
             DragManager.StartLinkDrag(this._linkButton.current, dragData, e.pageX, e.pageY, {
                 handlers: {
                     dragComplete: () => {
-                        let tooltipmenu = FormattedTextBox.ToolTipTextMenu;
-                        let linkDoc = dragData.linkDocument;
+                        const tooltipmenu = FormattedTextBox.ToolTipTextMenu;
+                        const linkDoc = dragData.linkDocument;
                         if (linkDoc && tooltipmenu) {
-                            let proto = Doc.GetProto(linkDoc);
+                            const proto = Doc.GetProto(linkDoc);
                             if (proto && docView) {
                                 proto.sourceContext = docView.props.ContainingCollectionDoc;
                             }
-                            let text = tooltipmenu.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), e.ctrlKey ? "onRight" : "inTab");
+                            const text = tooltipmenu.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), e.ctrlKey ? "onRight" : "inTab");
                             if (linkDoc instanceof Doc && linkDoc.anchor2 instanceof Doc) {
                                 proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODODO open to more descriptive descriptions of following in text link
                             }
@@ -152,21 +155,27 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
 
     @computed
     get considerGoogleDocsPush() {
-        let targetDoc = this.props.views[0].props.Document;
-        let published = Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
-        return <div title={`${published ? "Push" : "Publish"} to Google Docs`} className="documentButtonBar-linker" onClick={() => {
-            DocumentButtonBar.hasPushedHack = false;
-            targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1;
-        }}>
+        const targetDoc = this.props.views[0].props.Document;
+        const published = Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
+        const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
+        return <div
+            title={`${published ? "Push" : "Publish"} to Google Docs`}
+            className="documentButtonBar-linker"
+            style={{ animation }}
+            onClick={() => {
+                !published && runInAction(() => this.isAnimatingPulse = true);
+                DocumentButtonBar.hasPushedHack = false;
+                targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1;
+            }}>
             <FontAwesomeIcon className="documentdecorations-icon" icon={published ? (this.pushIcon as any) : cloud} size={published ? "sm" : "xs"} />
         </div>;
     }
 
     @computed
     get considerGoogleDocsPull() {
-        let targetDoc = this.props.views[0].props.Document;
-        let dataDoc = Doc.GetProto(targetDoc);
-        let animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
+        const targetDoc = this.props.views[0].props.Document;
+        const dataDoc = Doc.GetProto(targetDoc);
+        const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
         return !dataDoc[GoogleRef] ? (null) : <div className="documentButtonBar-linker"
             title={`${!dataDoc.unchanged ? "Pull from" : "Fetch"} Google Docs`}
             style={{ backgroundColor: this.pullColor }}
@@ -192,7 +201,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
 
     @computed
     get linkButton() {
-        let linkCount = LinkManager.Instance.getAllRelatedLinks(this.props.views[0].props.Document).length;
+        const linkCount = LinkManager.Instance.getAllRelatedLinks(this.props.views[0].props.Document).length;
         return <div title="Drag(create link) Tap(view links)" className="documentButtonBar-linkFlyout" ref={this._linkButton}>
             <Flyout anchorPoint={anchorPoints.RIGHT_TOP}
                 content={<LinkMenu docView={this.props.views[0]} addDocTab={this.props.views[0].props.addDocTab} changeFlyout={emptyFunction} />}>
@@ -214,13 +223,13 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
     }
 
     render() {
-        let templates: Map<Template, boolean> = new Map();
+        const templates: Map<Template, boolean> = new Map();
         Array.from(Object.values(Templates.TemplateList)).map(template =>
             templates.set(template, this.props.views.reduce((checked, doc) => checked || doc.getLayoutPropStr("show" + template.Name) ? true : false, false as boolean)));
 
-        let isText = this.props.views[0].props.Document.data instanceof RichTextField; // bcz: Todo - can't assume layout is using the 'data' field.  need to add fieldKey to DocumentView
-        let considerPull = isText && this.considerGoogleDocsPull;
-        let considerPush = isText && this.considerGoogleDocsPush;
+        const isText = this.props.views[0].props.Document.data instanceof RichTextField; // bcz: Todo - can't assume layout is using the 'data' field.  need to add fieldKey to DocumentView
+        const considerPull = isText && this.considerGoogleDocsPull;
+        const considerPush = isText && this.considerGoogleDocsPush;
         return <div className="documentButtonBar">
             <div className="documentButtonBar-button">
                 {this.linkButton}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 66f47147f..7b0c31e37 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -24,7 +24,6 @@ import { DocumentView } from "./nodes/DocumentView";
 import { FieldView } from "./nodes/FieldView";
 import { IconBox } from "./nodes/IconBox";
 import React = require("react");
-import { PointData } from '../../new_fields/InkField';
 import { DocumentType } from '../documents/DocumentTypes';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
@@ -68,8 +67,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     @observable public pushIcon: IconProp = "arrow-alt-circle-up";
     @observable public pullIcon: IconProp = "arrow-alt-circle-down";
     @observable public pullColor: string = "white";
-    @observable public isAnimatingFetch = false;
-    @observable public isAnimatingPulse = false;
     @observable public openHover = false;
 
     constructor(props: Readonly<{}>) {
@@ -82,25 +79,25 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     @action titleChanged = (event: any) => { this._title = event.target.value; };
     @action titleBlur = () => { this._edtingTitle = false; };
     @action titleEntered = (e: any) => {
-        var key = e.keyCode || e.which;
+        const key = e.keyCode || e.which;
         // enter pressed
         if (key === 13) {
-            var text = e.target.value;
+            const text = e.target.value;
             if (text[0] === '#') {
                 this._fieldKey = text.slice(1, text.length);
                 this._title = this.selectionTitle;
             } else if (text.startsWith("::")) {
-                let targetID = text.slice(2, text.length);
-                let promoteDoc = SelectionManager.SelectedDocuments()[0];
+                const targetID = text.slice(2, text.length);
+                const promoteDoc = SelectionManager.SelectedDocuments()[0];
                 DocUtils.Publish(promoteDoc.props.Document, targetID, promoteDoc.props.addDocument, promoteDoc.props.removeDocument);
             } else if (text.startsWith(">")) {
-                let fieldTemplateView = SelectionManager.SelectedDocuments()[0];
+                const fieldTemplateView = SelectionManager.SelectedDocuments()[0];
                 SelectionManager.DeselectAll();
-                let fieldTemplate = fieldTemplateView.props.Document;
-                let containerView = fieldTemplateView.props.ContainingCollectionView;
-                let docTemplate = fieldTemplateView.props.ContainingCollectionDoc;
+                const fieldTemplate = fieldTemplateView.props.Document;
+                const containerView = fieldTemplateView.props.ContainingCollectionView;
+                const docTemplate = fieldTemplateView.props.ContainingCollectionDoc;
                 if (containerView && docTemplate) {
-                    let metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length);
+                    const metaKey = text.startsWith(">>") ? text.slice(2, text.length) : text.slice(1, text.length);
                     if (metaKey !== containerView.props.fieldKey && containerView.props.DataDoc) {
                         const fd = fieldTemplate.data;
                         fd instanceof ObjectField && (Doc.GetProto(containerView.props.DataDoc)[metaKey] = ObjectField.MakeCopy(fd));
@@ -115,15 +112,15 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             else {
                 if (SelectionManager.SelectedDocuments().length > 0) {
                     SelectionManager.SelectedDocuments()[0].props.Document.customTitle = !this._title.startsWith("-");
-                    let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey];
+                    const field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey];
                     if (typeof field === "number") {
                         SelectionManager.SelectedDocuments().forEach(d => {
-                            let doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document;
+                            const doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document;
                             doc[this._fieldKey] = +this._title;
                         });
                     } else {
                         SelectionManager.SelectedDocuments().forEach(d => {
-                            let doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document;
+                            const doc = d.props.Document.proto ? d.props.Document.proto : d.props.Document;
                             doc[this._fieldKey] = this._title;
                         });
                     }
@@ -165,11 +162,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) {
                 return bounds;
             }
-            let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
+            const transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse();
             var [sptX, sptY] = transform.transformPoint(0, 0);
             let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight());
             if (documentView.props.Document.type === DocumentType.LINK) {
-                let rect = documentView.ContentDiv!.getElementsByClassName("docuLinkBox-cont")[0].getBoundingClientRect();
+                const rect = documentView.ContentDiv!.getElementsByClassName("docuLinkBox-cont")[0].getBoundingClientRect();
                 sptX = rect.left;
                 sptY = rect.top;
                 bptX = rect.right;
@@ -192,8 +189,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
     @action
     onBackgroundMove = (e: PointerEvent): void => {
-        let dragDocView = SelectionManager.SelectedDocuments()[0];
-        let dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
+        const dragDocView = SelectionManager.SelectedDocuments()[0];
+        const dragData = new DragManager.DocumentDragData(SelectionManager.SelectedDocuments().map(dv => dv.props.Document));
         const [left, top] = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).inverse().transformPoint(0, 0);
         dragData.offset = dragDocView.props.ScreenToLocalTransform().scale(dragDocView.props.ContentScaling()).transformDirection(e.x - left, e.y - top);
         dragData.moveDocument = SelectionManager.SelectedDocuments()[0].props.moveDocument;
@@ -256,8 +253,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             this._downX = e.pageX;
             this._downY = e.pageY;
             this._removeIcon = false;
-            let selDoc = SelectionManager.SelectedDocuments()[0];
-            let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0);
+            const selDoc = SelectionManager.SelectedDocuments()[0];
+            const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0);
             this._minimizedX = selDocPos[0] + 12;
             this._minimizedY = selDocPos[1] + 12;
             document.removeEventListener("pointermove", this.onMinimizeMove);
@@ -272,12 +269,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         e.stopPropagation();
         if (Math.abs(e.pageX - this._downX) > Utils.DRAG_THRESHOLD ||
             Math.abs(e.pageY - this._downY) > Utils.DRAG_THRESHOLD) {
-            let selDoc = SelectionManager.SelectedDocuments()[0];
-            let selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0);
-            let snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20;
+            const selDoc = SelectionManager.SelectedDocuments()[0];
+            const selDocPos = selDoc.props.ScreenToLocalTransform().scale(selDoc.props.ContentScaling()).inverse().transformPoint(0, 0);
+            const snapped = Math.abs(e.pageX - selDocPos[0]) < 20 && Math.abs(e.pageY - selDocPos[1]) < 20;
             this._minimizedX = snapped ? selDocPos[0] + 4 : e.clientX;
             this._minimizedY = snapped ? selDocPos[1] - 18 : e.clientY;
-            let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
+            const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
 
             if (selectedDocs.length > 1) {
                 this._iconDoc = this._iconDoc ? this._iconDoc : this.createIcon(SelectionManager.SelectedDocuments(), CollectionView.LayoutString(""));
@@ -295,15 +292,15 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         if (e.button === 0) {
             document.removeEventListener("pointermove", this.onMinimizeMove);
             document.removeEventListener("pointerup", this.onMinimizeUp);
-            let selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
+            const selectedDocs = SelectionManager.SelectedDocuments().map(sd => sd);
             if (this._iconDoc && selectedDocs.length === 1 && this._removeIcon) {
                 selectedDocs[0].props.removeDocument && selectedDocs[0].props.removeDocument(this._iconDoc);
             }
             if (!this._removeIcon && selectedDocs.length === 1) { // if you click on the top-left button when just 1 doc is selected, then collapse it.  not sure why we don't do it for multiple selections
                 this.getIconDoc(selectedDocs[0]).then(async icon => {
-                    let minimizedDoc = await Cast(selectedDocs[0].props.Document.minimizedDoc, Doc);
+                    const minimizedDoc = await Cast(selectedDocs[0].props.Document.minimizedDoc, Doc);
                     if (minimizedDoc) {
-                        let scrpt = selectedDocs[0].props.ScreenToLocalTransform().scale(selectedDocs[0].props.ContentScaling()).inverse().transformPoint(
+                        const scrpt = selectedDocs[0].props.ScreenToLocalTransform().scale(selectedDocs[0].props.ContentScaling()).inverse().transformPoint(
                             NumCast(minimizedDoc.x) - NumCast(selectedDocs[0].Document.x), NumCast(minimizedDoc.y) - NumCast(selectedDocs[0].Document.y));
                         SelectionManager.DeselectAll();
                         DocumentManager.Instance.animateBetweenPoint(scrpt, await DocListCastAsync(minimizedDoc.maximizedDocs));
@@ -317,8 +314,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
     @undoBatch
     @action createIcon = (selected: DocumentView[], layoutString: string): Doc => {
-        let doc = selected[0].props.Document;
-        let iconDoc = Docs.Create.IconDocument(layoutString);
+        const doc = selected[0].props.Document;
+        const iconDoc = Docs.Create.IconDocument(layoutString);
         iconDoc.isButton = true;
 
         IconBox.AutomaticTitle(iconDoc);
@@ -334,7 +331,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     }
     @action
     public getIconDoc = async (docView: DocumentView): Promise<Doc | undefined> => {
-        let doc = docView.props.Document;
+        const doc = docView.props.Document;
         let iconDoc: Doc | undefined = await Cast(doc.minimizedDoc, Doc);
 
         if (!iconDoc || !DocumentManager.Instance.getDocumentView(iconDoc)) {
@@ -344,8 +341,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         return iconDoc;
     }
     moveIconDoc(iconDoc: Doc) {
-        let selView = SelectionManager.SelectedDocuments()[0];
-        let where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()).
+        const selView = SelectionManager.SelectedDocuments()[0];
+        const where = (selView.props.ScreenToLocalTransform()).scale(selView.props.ContentScaling()).
             transformPoint(this._minimizedX - 12, this._minimizedY - 12);
         iconDoc.x = where[0] + NumCast(selView.props.Document.x);
         iconDoc.y = where[1] + NumCast(selView.props.Document.y);
@@ -370,8 +367,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         dist = dist < 3 ? 0 : dist;
         let usingRule = false;
         SelectionManager.SelectedDocuments().map(dv => {
-            let ruleProvider = dv.props.ruleProvider;
-            let heading = NumCast(dv.props.Document.heading);
+            const ruleProvider = dv.props.ruleProvider;
+            const heading = NumCast(dv.props.Document.heading);
             ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`);
             usingRule = usingRule || (ruleProvider && heading ? true : false);
         });
@@ -419,8 +416,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
         let dX = 0, dY = 0, dW = 0, dH = 0;
 
-        let moveX = e.clientX - this._lastX; // e.movementX;
-        let moveY = e.clientY - this._lastY; // e.movementY;
+        const moveX = e.clientX - this._lastX; // e.movementX;
+        const moveY = e.clientY - this._lastY; // e.movementY;
         this._lastX = e.clientX;
         this._lastY = e.clientY;
 
@@ -465,18 +462,18 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
         SelectionManager.SelectedDocuments().forEach(action((element: DocumentView) => {
             if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) {
-                let doc = PositionDocument(element.props.Document);
-                let layoutDoc = PositionDocument(Doc.Layout(element.props.Document));
+                const doc = PositionDocument(element.props.Document);
+                const layoutDoc = PositionDocument(Doc.Layout(element.props.Document));
                 let nwidth = layoutDoc.nativeWidth || 0;
                 let nheight = layoutDoc.nativeHeight || 0;
-                let width = (layoutDoc.width || 0);
-                let height = (layoutDoc.height || (nheight / nwidth * width));
-                let scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling();
-                let actualdW = Math.max(width + (dW * scale), 20);
-                let actualdH = Math.max(height + (dH * scale), 20);
+                const width = (layoutDoc.width || 0);
+                const height = (layoutDoc.height || (nheight / nwidth * width));
+                const scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling();
+                const actualdW = Math.max(width + (dW * scale), 20);
+                const actualdH = Math.max(height + (dH * scale), 20);
                 doc.x = (doc.x || 0) + dX * (actualdW - width);
                 doc.y = (doc.y || 0) + dY * (actualdH - height);
-                let fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight);
+                const fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight);
                 if (fixedAspect && e.ctrlKey && layoutDoc.ignoreAspect) {
                     layoutDoc.ignoreAspect = false;
                     layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0;
@@ -529,8 +526,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     @computed
     get selectionTitle(): string {
         if (SelectionManager.SelectedDocuments().length === 1) {
-            let selected = SelectionManager.SelectedDocuments()[0];
-            let field = selected.props.Document[this._fieldKey];
+            const selected = SelectionManager.SelectedDocuments()[0];
+            const field = selected.props.Document[this._fieldKey];
             if (typeof field === "string") {
                 return field;
             }
@@ -555,12 +552,12 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         }
     }
     render() {
-        var bounds = this.Bounds;
-        let seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined;
+        const bounds = this.Bounds;
+        const seldoc = SelectionManager.SelectedDocuments().length ? SelectionManager.SelectedDocuments()[0] : undefined;
         if (SelectionManager.GetIsDragging() || bounds.x === Number.MAX_VALUE || !seldoc || this._hidden || isNaN(bounds.r) || isNaN(bounds.b) || isNaN(bounds.x) || isNaN(bounds.y)) {
             return (null);
         }
-        let minimizeIcon = (
+        const minimizeIcon = (
             <div className="documentDecorations-minimizeButton" onPointerDown={this.onMinimizeDown}>
                 {/* Currently, this is set to be enabled if there is no ink selected. It might be interesting to think about minimizing ink if it's useful? -syip2*/}
                 {SelectionManager.SelectedDocuments().length === 1 ? IconBox.DocumentIcon(StrCast(SelectionManager.SelectedDocuments()[0].props.Document.layout, "...")) : "..."}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 8f397e331..edc7df12a 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -25,7 +25,7 @@ export default class KeyManager {
     private router = new Map<string, KeyHandler>();
 
     constructor() {
-        let isMac = navigator.platform.toLowerCase().indexOf("mac") >= 0;
+        const isMac = navigator.platform.toLowerCase().indexOf("mac") >= 0;
 
         // SHIFT CONTROL ALT META
         this.router.set("0000", this.unmodified);
@@ -36,22 +36,22 @@ export default class KeyManager {
     }
 
     public handle = async (e: KeyboardEvent) => {
-        let keyname = e.key && e.key.toLowerCase();
+        const keyname = e.key && e.key.toLowerCase();
         this.handleGreedy(keyname);
 
         if (modifiers.includes(keyname)) {
             return;
         }
 
-        let bit = (value: boolean) => value ? "1" : "0";
-        let modifierIndex = bit(e.shiftKey) + bit(e.ctrlKey) + bit(e.altKey) + bit(e.metaKey);
+        const bit = (value: boolean) => value ? "1" : "0";
+        const modifierIndex = bit(e.shiftKey) + bit(e.ctrlKey) + bit(e.altKey) + bit(e.metaKey);
 
-        let handleConstrained = this.router.get(modifierIndex);
+        const handleConstrained = this.router.get(modifierIndex);
         if (!handleConstrained) {
             return;
         }
 
-        let control = await handleConstrained(keyname, e);
+        const control = await handleConstrained(keyname, e);
 
         control.stopPropagation && e.stopPropagation();
         control.preventDefault && e.preventDefault();
@@ -65,7 +65,7 @@ export default class KeyManager {
     private unmodified = action((keyname: string, e: KeyboardEvent) => {
         switch (keyname) {
             case "escape":
-                let main = MainView.Instance;
+                const main = MainView.Instance;
                 InkingControl.Instance.switchTool(InkTool.None);
                 if (main.isPointerDown) {
                     DragManager.AbortDrag();
@@ -89,8 +89,8 @@ export default class KeyManager {
                 }
                 UndoManager.RunInBatch(() => {
                     SelectionManager.SelectedDocuments().map(docView => {
-                        let doc = docView.props.Document;
-                        let remove = docView.props.removeDocument;
+                        const doc = docView.props.Document;
+                        const remove = docView.props.removeDocument;
                         remove && remove(doc);
                     });
                 }, "delete");
@@ -121,8 +121,8 @@ export default class KeyManager {
     }
 
     private alt = action((keyname: string) => {
-        let stopPropagation = true;
-        let preventDefault = true;
+        const stopPropagation = true;
+        const preventDefault = true;
 
         switch (keyname) {
             // case "n":
@@ -190,7 +190,7 @@ export default class KeyManager {
                 }
                 break;
             case "o":
-                let target = SelectionManager.SelectedDocuments()[0];
+                const target = SelectionManager.SelectedDocuments()[0];
                 target && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(target);
                 break;
             case "r":
@@ -220,12 +220,12 @@ export default class KeyManager {
     });
 
     async printClipboard() {
-        let text: string = await navigator.clipboard.readText();
+        const text: string = await navigator.clipboard.readText();
     }
 
     private ctrl_shift = action((keyname: string) => {
-        let stopPropagation = true;
-        let preventDefault = true;
+        const stopPropagation = true;
+        const preventDefault = true;
 
         switch (keyname) {
             case "z":
diff --git a/src/client/views/InkSelectDecorations.tsx b/src/client/views/InkSelectDecorations.tsx
index d40df9b75..3ad50762d 100644
--- a/src/client/views/InkSelectDecorations.tsx
+++ b/src/client/views/InkSelectDecorations.tsx
@@ -29,10 +29,10 @@ export default class InkSelectDecorations extends Touchable {
 
     @computed
     get Bounds(): { x: number, y: number, b: number, r: number } {
-        let left = Number.MAX_VALUE;
-        let top = Number.MAX_VALUE;
-        let right = -Number.MAX_VALUE;
-        let bottom = -Number.MAX_VALUE;
+        const left = Number.MAX_VALUE;
+        const top = Number.MAX_VALUE;
+        const right = -Number.MAX_VALUE;
+        const bottom = -Number.MAX_VALUE;
         this._selectedInkNodes.forEach((value: PointData, key: string) => {
             // value.pathData.map(val => {
             //     left = Math.min(val.x, left);
@@ -45,7 +45,7 @@ export default class InkSelectDecorations extends Touchable {
     }
 
     render() {
-        let bounds = this.Bounds;
+        const bounds = this.Bounds;
         return <div style={{
             top: bounds.y, left: bounds.x,
             height: bounds.b - bounds.y,
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index 75faa9641..e33f193b8 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -1,5 +1,5 @@
 import { action, computed, observable } from "mobx";
-import { ColorResult } from 'react-color';
+import { ColorState } from 'react-color';
 import { Doc } from "../../new_fields/Doc";
 import { InkTool } from "../../new_fields/InkField";
 import { List } from "../../new_fields/List";
@@ -35,16 +35,16 @@ export class InkingControl {
     }
 
     @undoBatch
-    switchColor = action((color: ColorResult): void => {
+    switchColor = action((color: ColorState): void => {
         this._selectedColor = color.hex + (color.rgb.a !== undefined ? this.decimalToHexString(Math.round(color.rgb.a * 255)) : "ff");
 
         if (InkingControl.Instance.selectedTool === InkTool.None) {
-            let selected = SelectionManager.SelectedDocuments();
-            let oldColors = selected.map(view => {
-                let targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory :
+            const selected = SelectionManager.SelectedDocuments();
+            const oldColors = selected.map(view => {
+                const targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory :
                     view.props.Document.layout instanceof Doc ? view.props.Document.layout :
                         view.props.Document.isTemplateField ? view.props.Document : Doc.GetProto(view.props.Document);
-                let sel = window.getSelection();
+                const sel = window.getSelection();
                 if (StrCast(targetDoc.layout).indexOf("FormattedTextBox") !== -1 && (!sel || sel.toString() !== "")) {
                     targetDoc.color = this._selectedColor;
                     return {
@@ -52,24 +52,24 @@ export class InkingControl {
                         previous: StrCast(targetDoc.color)
                     };
                 }
-                let oldColor = StrCast(targetDoc.backgroundColor);
+                const oldColor = StrCast(targetDoc.backgroundColor);
                 let matchedColor = this._selectedColor;
                 const cvd = view.props.ContainingCollectionDoc;
                 let ruleProvider = view.props.ruleProvider;
                 if (cvd) {
                     if (!cvd.colorPalette) {
-                        let defaultPalette = ["rg(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
+                        const defaultPalette = ["rg(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
                             "rgb(209,150,226)", "rgb(127,235,144)", "rgb(252,188,189)", "rgb(247,175,81)",];
-                        let colorPalette = Cast(cvd.colorPalette, listSpec("string"));
+                        const colorPalette = Cast(cvd.colorPalette, listSpec("string"));
                         if (!colorPalette) cvd.colorPalette = new List<string>(defaultPalette);
                     }
-                    let cp = Cast(cvd.colorPalette, listSpec("string")) as string[];
+                    const cp = Cast(cvd.colorPalette, listSpec("string")) as string[];
                     let closest = 0;
                     let dist = 10000000;
-                    let ccol = Utils.fromRGBAstr(StrCast(targetDoc.backgroundColor));
+                    const ccol = Utils.fromRGBAstr(StrCast(targetDoc.backgroundColor));
                     for (let i = 0; i < cp.length; i++) {
-                        let cpcol = Utils.fromRGBAstr(cp[i]);
-                        let d = Math.sqrt((ccol.r - cpcol.r) * (ccol.r - cpcol.r) + (ccol.b - cpcol.b) * (ccol.b - cpcol.b) + (ccol.g - cpcol.g) * (ccol.g - cpcol.g));
+                        const cpcol = Utils.fromRGBAstr(cp[i]);
+                        const d = Math.sqrt((ccol.r - cpcol.r) * (ccol.r - cpcol.r) + (ccol.b - cpcol.b) * (ccol.b - cpcol.b) + (ccol.g - cpcol.g) * (ccol.g - cpcol.g));
                         if (d < dist) {
                             dist = d;
                             closest = i;
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index a27f106e3..7cee84fc5 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -14,7 +14,7 @@ type InkDocument = makeInterface<[typeof documentSchema]>;
 const InkDocument = makeInterface(documentSchema);
 
 export function CreatePolyline(points: { x: number, y: number }[], left: number, top: number, color?: string, width?: number) {
-    let pts = points.reduce((acc: string, pt: { x: number, y: number }) => acc + `${pt.x - left},${pt.y - top} `, "");
+    const pts = points.reduce((acc: string, pt: { x: number, y: number }) => acc + `${pt.x - left},${pt.y - top} `, "");
     return (
         <polyline
             points={pts}
@@ -35,18 +35,18 @@ export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocu
     @computed get PanelHeight() { return this.props.PanelHeight(); }
 
     render() {
-        let data: InkData = Cast(this.Document.data, InkField)?.inkData ?? [];
-        let xs = data.map(p => p.x);
-        let ys = data.map(p => p.y);
-        let left = Math.min(...xs);
-        let top = Math.min(...ys);
-        let right = Math.max(...xs);
-        let bottom = Math.max(...ys);
-        let points = CreatePolyline(data, 0, 0, this.Document.color, this.Document.strokeWidth);
-        let width = right - left;
-        let height = bottom - top;
-        let scaleX = this.PanelWidth / width;
-        let scaleY = this.PanelHeight / height;
+        const data: InkData = Cast(this.Document.data, InkField)?.inkData ?? [];
+        const xs = data.map(p => p.x);
+        const ys = data.map(p => p.y);
+        const left = Math.min(...xs);
+        const top = Math.min(...ys);
+        const right = Math.max(...xs);
+        const bottom = Math.max(...ys);
+        const points = CreatePolyline(data, 0, 0, this.Document.color, this.Document.strokeWidth);
+        const width = right - left;
+        const height = bottom - top;
+        const scaleX = this.PanelWidth / width;
+        const scaleY = this.PanelHeight / height;
         return (
             <svg width={width} height={height} style={{
                 transformOrigin: "top left",
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 291781da1..bd20cbcf1 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -60,10 +60,10 @@ export class MainView extends React.Component {
     public isPointerDown = false;
 
     componentWillMount() {
-        var tag = document.createElement('script');
+        const tag = document.createElement('script');
 
         tag.src = "https://www.youtube.com/iframe_api";
-        var firstScriptTag = document.getElementsByTagName('script')[0];
+        const firstScriptTag = document.getElementsByTagName('script')[0];
         firstScriptTag.parentNode!.insertBefore(tag, firstScriptTag);
         window.removeEventListener("keydown", KeyManager.Instance.handle);
         window.addEventListener("keydown", KeyManager.Instance.handle);
@@ -82,9 +82,9 @@ export class MainView extends React.Component {
         // causes errors to be generated when modifying an observable outside of an action
         configure({ enforceActions: "observed" });
         if (window.location.pathname !== "/home") {
-            let pathname = window.location.pathname.substr(1).split("/");
+            const pathname = window.location.pathname.substr(1).split("/");
             if (pathname.length > 1) {
-                let type = pathname[0];
+                const type = pathname[0];
                 if (type === "doc") {
                     CurrentUserUtils.MainDocId = pathname[1];
                     if (!this.userDoc) {
@@ -158,7 +158,7 @@ export class MainView extends React.Component {
 
     initAuthenticationRouters = async () => {
         // Load the user's active workspace, or create a new one if initial session after signup
-        let received = CurrentUserUtils.MainDocId;
+        const received = CurrentUserUtils.MainDocId;
         if (received && !this.userDoc) {
             reaction(
                 () => CurrentUserUtils.GuestTarget,
@@ -175,7 +175,7 @@ export class MainView extends React.Component {
                     }),
                 );
             }
-            let doc = this.userDoc && await Cast(this.userDoc.activeWorkspace, Doc);
+            const doc = this.userDoc && await Cast(this.userDoc.activeWorkspace, Doc);
             if (doc) {
                 this.openWorkspace(doc);
             } else {
@@ -186,9 +186,9 @@ export class MainView extends React.Component {
 
     @action
     createNewWorkspace = async (id?: string) => {
-        let workspaces = Cast(this.userDoc.workspaces, Doc) as Doc;
-        let workspaceCount = DocListCast(workspaces.data).length + 1;
-        let freeformOptions: DocumentOptions = {
+        const workspaces = Cast(this.userDoc.workspaces, Doc) as Doc;
+        const workspaceCount = DocListCast(workspaces.data).length + 1;
+        const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
             width: this._panelWidth * .7,
@@ -196,10 +196,10 @@ export class MainView extends React.Component {
             title: "Collection " + workspaceCount,
             backgroundColor: "white"
         };
-        let freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
+        const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
         Doc.AddDocToList(Doc.GetProto(CurrentUserUtils.UserDocument.documents as Doc), "data", freeformDoc);
-        var dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
-        let mainDoc = Docs.Create.DockDocument([freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${workspaceCount}` }, id);
+        const dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
+        const mainDoc = Docs.Create.DockDocument([freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${workspaceCount}` }, id);
         Doc.AddDocToList(workspaces, "data", mainDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
         setTimeout(() => this.openWorkspace(mainDoc), 0);
@@ -213,7 +213,7 @@ export class MainView extends React.Component {
             !("presentationView" in doc) && (doc.presentationView = new List<Doc>([Docs.Create.TreeDocument([], { title: "Presentation" })]));
             this.userDoc ? (this.userDoc.activeWorkspace = doc) : (CurrentUserUtils.GuestWorkspace = doc);
         }
-        let state = this._urlState;
+        const state = this._urlState;
         if (state.sharing === true && !this.userDoc) {
             DocServer.Control.makeReadOnly();
         } else {
@@ -263,8 +263,8 @@ export class MainView extends React.Component {
 
     @computed get dockingContent() {
         const mainContainer = this.mainContainer;
-        let flyoutWidth = this.flyoutWidth; // bcz: need to be here because Measure messes with observables.
-        let flyoutTranslate = this._flyoutTranslate;
+        const flyoutWidth = this.flyoutWidth; // bcz: need to be here because Measure messes with observables.
+        const flyoutTranslate = this._flyoutTranslate;
         return <Measure offset onResize={this.onResize}>
             {({ measureRef }) =>
                 <div ref={measureRef} id="mainContent-div" style={{ width: `calc(100% - ${flyoutTranslate ? flyoutWidth : 0}px`, transform: `translate(${flyoutTranslate ? flyoutWidth : 0}px, 0px)` }} onDrop={this.onDrop}>
@@ -352,11 +352,11 @@ export class MainView extends React.Component {
     mainContainerXf = () => new Transform(0, -this._buttonBarHeight, 1);
 
     @computed get flyout() {
-        let sidebarContent = this.userDoc && this.userDoc.sidebarContainer;
+        const sidebarContent = this.userDoc && this.userDoc.sidebarContainer;
         if (!(sidebarContent instanceof Doc)) {
             return (null);
         }
-        let sidebarButtonsDoc = Cast(CurrentUserUtils.UserDocument.sidebarButtons, Doc) as Doc;
+        const sidebarButtonsDoc = Cast(CurrentUserUtils.UserDocument.sidebarButtons, Doc) as Doc;
         sidebarButtonsDoc.columnWidth = this.flyoutWidth / 3 - 30;
         return <div className="mainView-flyoutContainer" >
             <div className="mainView-tabButtons" style={{ height: `${this._buttonBarHeight}px` }}>
@@ -463,7 +463,7 @@ export class MainView extends React.Component {
 
     buttonBarXf = () => {
         if (!this._docBtnRef.current) return Transform.Identity();
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
         return new Transform(-translateX, -translateY, 1 / scale);
     }
     @computed get docButtons() {
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 221a0260a..9198fe3e3 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -14,9 +14,9 @@ export interface MainViewOverlayProps {
 export default class MainViewModal extends React.Component<MainViewOverlayProps> {
 
     render() {
-        let p = this.props;
-        let dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
-        let overlayOpacity = p.overlayDisplayedOpacity || 0.4;
+        const p = this.props;
+        const dialogueOpacity = p.dialogueBoxDisplayedOpacity || 1;
+        const overlayOpacity = p.overlayDisplayedOpacity || 0.4;
         return !p.isDisplayed ? (null) : (
             <div style={{ pointerEvents: p.isDisplayed ? p.interactive ? "all" : "none" : "none" }}>
                 <div
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 41453f8b2..8859c14cb 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -99,8 +99,8 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
             } else {
                 let childSuccess = true;
                 if (this._addChildren) {
-                    for (let document of doc) {
-                        let collectionChildren = await DocListCastAsync(document.data);
+                    for (const document of doc) {
+                        const collectionChildren = await DocListCastAsync(document.data);
                         if (collectionChildren) {
                             childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script));
                         }
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 9869e24d1..32ada293c 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -148,7 +148,7 @@ export class OverlayView extends React.Component {
         return CurrentUserUtils.UserDocument.overlays instanceof Doc && DocListCast(CurrentUserUtils.UserDocument.overlays.data).map(d => {
             d.inOverlay = true;
             let offsetx = 0, offsety = 0;
-            let onPointerMove = action((e: PointerEvent) => {
+            const onPointerMove = action((e: PointerEvent) => {
                 if (e.buttons === 1) {
                     d.x = e.clientX + offsetx;
                     d.y = e.clientY + offsety;
@@ -156,14 +156,14 @@ export class OverlayView extends React.Component {
                     e.preventDefault();
                 }
             });
-            let onPointerUp = action((e: PointerEvent) => {
+            const onPointerUp = action((e: PointerEvent) => {
                 document.removeEventListener("pointermove", onPointerMove);
                 document.removeEventListener("pointerup", onPointerUp);
                 e.stopPropagation();
                 e.preventDefault();
             });
 
-            let onPointerDown = (e: React.PointerEvent) => {
+            const onPointerDown = (e: React.PointerEvent) => {
                 offsetx = NumCast(d.x) - e.clientX;
                 offsety = NumCast(d.y) - e.clientY;
                 e.stopPropagation();
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 136a272ab..fd0287b6c 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -26,7 +26,7 @@ export class PreviewCursor extends React.Component<{}> {
     paste = (e: ClipboardEvent) => {
         if (PreviewCursor.Visible) {
             if (e.clipboardData) {
-                let newPoint = PreviewCursor._getTransform().transformPoint(PreviewCursor._clickPoint[0], PreviewCursor._clickPoint[1]);
+                const newPoint = PreviewCursor._getTransform().transformPoint(PreviewCursor._clickPoint[0], PreviewCursor._clickPoint[1]);
                 runInAction(() => { PreviewCursor.Visible = false; });
 
 
@@ -44,7 +44,7 @@ export class PreviewCursor extends React.Component<{}> {
                     }
 
                     // tests for URL and makes web document
-                    let re: any = /^https?:\/\//g;
+                    const re: any = /^https?:\/\//g;
                     if (re.test(e.clipboardData.getData("text/plain"))) {
                         const url = e.clipboardData.getData("text/plain");
                         PreviewCursor._addDocument(Docs.Create.WebDocument(url, {
@@ -56,7 +56,7 @@ export class PreviewCursor extends React.Component<{}> {
                     }
 
                     // creates text document
-                    let newBox = Docs.Create.TextDocument({
+                    const newBox = Docs.Create.TextDocument({
                         width: 200, height: 100,
                         x: newPoint[0],
                         y: newPoint[1],
@@ -69,10 +69,10 @@ export class PreviewCursor extends React.Component<{}> {
                 }
                 //pasting in images
                 if (e.clipboardData.getData("text/html") !== "" && e.clipboardData.getData("text/html").includes("<img src=")) {
-                    let re: any = /<img src="(.*?)"/g;
-                    let arr: any[] = re.exec(e.clipboardData.getData("text/html"));
+                    const re: any = /<img src="(.*?)"/g;
+                    const arr: any[] = re.exec(e.clipboardData.getData("text/html"));
 
-                    let img: Doc = Docs.Create.ImageDocument(
+                    const img: Doc = Docs.Create.ImageDocument(
                         arr[1], {
                         width: 300, title: arr[1],
                         x: newPoint[0],
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index 8ef9f3be6..65d96f364 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -59,7 +59,7 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
             onFocus = this.onFocus;
             onBlur = this.onBlur;
         }
-        let params = <EditableView
+        const params = <EditableView
             contents={""}
             display={"block"}
             maxHeight={72}
@@ -96,9 +96,9 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
             }
         }
         // tslint:disable-next-line: no-unnecessary-callback-wrapper
-        let params: string[] = [];
-        let setParams = (p: string[]) => params.splice(0, params.length, ...p);
-        let scriptingBox = <ScriptBox initialText={originalText} setParams={setParams} onCancel={overlayDisposer} onSave={(text, onError) => {
+        const params: string[] = [];
+        const setParams = (p: string[]) => params.splice(0, params.length, ...p);
+        const scriptingBox = <ScriptBox initialText={originalText} setParams={setParams} onCancel={overlayDisposer} onSave={(text, onError) => {
             if (prewrapper) {
                 text = prewrapper + text + (postwrapper ? postwrapper : "");
             }
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index c65b338b4..e6116ca09 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -61,19 +61,19 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
 
     toggleFloat = (e: React.ChangeEvent<HTMLInputElement>): void => {
         SelectionManager.DeselectAll();
-        let topDocView = this.props.docs[0];
-        let topDoc = topDocView.props.Document;
-        let xf = topDocView.props.ScreenToLocalTransform();
-        let ex = e.target.clientLeft;
-        let ey = e.target.clientTop;
+        const topDocView = this.props.docs[0];
+        const topDoc = topDocView.props.Document;
+        const xf = topDocView.props.ScreenToLocalTransform();
+        const ex = e.target.clientLeft;
+        const ey = e.target.clientTop;
         undoBatch(action(() => topDoc.z = topDoc.z ? 0 : 1))();
         if (e.target.checked) {
             setTimeout(() => {
-                let newDocView = DocumentManager.Instance.getDocumentView(topDoc);
+                const newDocView = DocumentManager.Instance.getDocumentView(topDoc);
                 if (newDocView) {
-                    let de = new DragManager.DocumentDragData([topDoc]);
+                    const de = new DragManager.DocumentDragData([topDoc]);
                     de.moveDocument = topDocView.props.moveDocument;
-                    let xf = newDocView.ContentDiv!.getBoundingClientRect();
+                    const xf = newDocView.ContentDiv!.getBoundingClientRect();
                     DragManager.StartDocumentDrag([newDocView.ContentDiv!], de, ex, ey, {
                         offsetX: (ex - xf.left), offsetY: (ey - xf.top),
                         handlers: { dragComplete: () => { }, },
@@ -82,9 +82,9 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
                 }
             }, 10);
         } else if (topDocView.props.ContainingCollectionView) {
-            let collView = topDocView.props.ContainingCollectionView;
-            let [sx, sy] = xf.inverse().transformPoint(0, 0);
-            let [x, y] = collView.props.ScreenToLocalTransform().transformPoint(sx, sy);
+            const collView = topDocView.props.ContainingCollectionView;
+            const [sx, sy] = xf.inverse().transformPoint(0, 0);
+            const [x, y] = collView.props.ScreenToLocalTransform().transformPoint(sx, sy);
             topDoc.x = x;
             topDoc.y = y;
         }
@@ -122,7 +122,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
     @action
     toggleChrome = (): void => {
         this.props.docs.map(dv => {
-            let layout = Doc.Layout(dv.Document);
+            const layout = Doc.Layout(dv.Document);
             layout.chromeStatus = (layout.chromeStatus !== "disabled" ? "disabled" : "enabled");
         });
     }
@@ -147,8 +147,8 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
             document.removeEventListener("pointermove", this.onAliasButtonMoved);
             document.removeEventListener("pointerup", this.onAliasButtonUp);
 
-            let dragDocView = this.props.docs[0];
-            let dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
+            const dragDocView = this.props.docs[0];
+            const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
             const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             dragData.embedDoc = true;
             dragData.dropAction = "alias";
@@ -165,8 +165,8 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
     }
 
     render() {
-        let layout = Doc.Layout(this.props.docs[0].Document);
-        let templateMenu: Array<JSX.Element> = [];
+        const layout = Doc.Layout(this.props.docs[0].Document);
+        const templateMenu: Array<JSX.Element> = [];
         this.props.templates.forEach((checked, template) =>
             templateMenu.push(<TemplateToggle key={template.Name} template={template} checked={checked} toggle={this.toggleTemplate} />));
         templateMenu.push(<OtherToggle key={"float"} name={"Float"} checked={this.props.docs[0].Document.z ? true : false} toggle={this.toggleFloat} />);
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 0056a1d96..183d3e4e8 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -17,7 +17,7 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
     @action
     protected onTouchStart = (e: React.TouchEvent): void => {
         for (let i = 0; i < e.targetTouches.length; i++) {
-            let pt: any = e.targetTouches.item(i);
+            const pt: any = e.targetTouches.item(i);
             // pen is also a touch, but with a radius of 0.5 (at least with the surface pens). i doubt anyone's fingers are 2 pixels wide,
             // and this seems to be the only way of differentiating pen and touch on touch events
             if (pt.radiusX > 2 && pt.radiusY > 2) {
@@ -59,7 +59,7 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
         }
 
         for (let i = 0; i < e.targetTouches.length; i++) {
-            let pt = e.targetTouches.item(i);
+            const pt = e.targetTouches.item(i);
             if (pt) {
                 if (this.prevPoints.has(pt.identifier)) {
                     this.prevPoints.set(pt.identifier, pt);
@@ -78,7 +78,7 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
 
         // remove all the touches associated with the event
         for (let i = 0; i < e.targetTouches.length; i++) {
-            let pt = e.targetTouches.item(i);
+            const pt = e.targetTouches.item(i);
             if (pt) {
                 if (this.prevPoints.has(pt.identifier)) {
                     this.prevPoints.delete(pt.identifier);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 3040e74b0..77e6e1c93 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -96,13 +96,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @undoBatch
     @action
     public OpenFullScreen(docView: DocumentView) {
-        let document = Doc.MakeAlias(docView.props.Document);
-        let dataDoc = docView.props.DataDoc;
-        let newItemStackConfig = {
+        const document = Doc.MakeAlias(docView.props.Document);
+        const dataDoc = docView.props.DataDoc;
+        const newItemStackConfig = {
             type: 'stack',
             content: [CollectionDockingView.makeDocumentConfig(document, dataDoc)]
         };
-        var docconfig = this._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, this._goldenLayout);
+        const docconfig = this._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, this._goldenLayout);
         this._goldenLayout.root.contentItems[0].addChild(docconfig);
         docconfig.callDownwards('_$init');
         this._goldenLayout._$maximiseItem(docconfig);
@@ -113,7 +113,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
 
     public CloseFullScreen = () => {
-        let target = this._goldenLayout._maximisedItem;
+        const target = this._goldenLayout._maximisedItem;
         if (target !== null && this._maximizedSrc) {
             this._goldenLayout._maximisedItem.remove();
             SelectionManager.SelectDoc(this._maximizedSrc, false);
@@ -130,7 +130,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     public static CloseRightSplit(document: Doc): boolean {
         if (!CollectionDockingView.Instance) return false;
-        let instance = CollectionDockingView.Instance;
+        const instance = CollectionDockingView.Instance;
         let retVal = false;
         if (instance._goldenLayout.root.contentItems[0].isRow) {
             retVal = Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => {
@@ -176,21 +176,21 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     public static AddRightSplit(document: Doc, dataDoc: Doc | undefined, minimize: boolean = false) {
         if (!CollectionDockingView.Instance) return false;
-        let instance = CollectionDockingView.Instance;
-        let newItemStackConfig = {
+        const instance = CollectionDockingView.Instance;
+        const newItemStackConfig = {
             type: 'stack',
             content: [CollectionDockingView.makeDocumentConfig(document, dataDoc)]
         };
 
-        var newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
+        const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
 
         if (instance._goldenLayout.root.contentItems.length === 0) {
             instance._goldenLayout.root.addChild(newContentItem);
         } else if (instance._goldenLayout.root.contentItems[0].isRow) {
             instance._goldenLayout.root.contentItems[0].addChild(newContentItem);
         } else {
-            var collayout = instance._goldenLayout.root.contentItems[0];
-            var newRow = collayout.layoutManager.createContentItem({ type: "row" }, instance._goldenLayout);
+            const collayout = instance._goldenLayout.root.contentItems[0];
+            const newRow = collayout.layoutManager.createContentItem({ type: "row" }, instance._goldenLayout);
             collayout.parent.replaceChild(collayout, newRow);
 
             newRow.addChild(newContentItem, undefined, true);
@@ -213,7 +213,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     public AddTab = (stack: any, document: Doc, dataDocument: Doc | undefined) => {
         Doc.GetProto(document).lastOpened = new DateField;
-        let docContentConfig = CollectionDockingView.makeDocumentConfig(document, dataDocument);
+        const docContentConfig = CollectionDockingView.makeDocumentConfig(document, dataDocument);
         if (stack === undefined) {
             let stack: any = this._goldenLayout.root;
             while (!stack.isStack) {
@@ -236,7 +236,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
 
     setupGoldenLayout() {
-        var config = StrCast(this.props.Document.dockingConfig);
+        const config = StrCast(this.props.Document.dockingConfig);
         if (config) {
             if (!this._goldenLayout) {
                 runInAction(() => this._goldenLayout = new GoldenLayout(JSON.parse(config)));
@@ -280,7 +280,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                         // Because this is in a set timeout, if this component unmounts right after mounting,
                         // we will leak a GoldenLayout, because we try to destroy it before we ever create it
                         setTimeout(() => this.setupGoldenLayout(), 1);
-                        let userDoc = CurrentUserUtils.UserDocument;
+                        const userDoc = CurrentUserUtils.UserDocument;
                         userDoc && DocListCast((userDoc.workspaces as Doc).data).map(d => d.workspaceBrush = false);
                         this.props.Document.workspaceBrush = true;
                     }
@@ -311,7 +311,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
     @action
     onResize = (event: any) => {
-        var cur = this._containerRef.current;
+        const cur = this._containerRef.current;
 
         // bcz: since GoldenLayout isn't a React component itself, we need to notify it to resize when its document container's size has changed
         this._goldenLayout && this._goldenLayout.updateSize(cur!.getBoundingClientRect().width, cur!.getBoundingClientRect().height);
@@ -330,19 +330,19 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     @action
     onPointerDown = (e: React.PointerEvent): void => {
         this._isPointerDown = true;
-        let onPointerUp = action(() => {
+        const onPointerUp = action(() => {
             window.removeEventListener("pointerup", onPointerUp);
             this._isPointerDown = false;
         });
         window.addEventListener("pointerup", onPointerUp);
-        var className = (e.target as any).className;
+        const className = (e.target as any).className;
         if (className === "messageCounter") {
             e.stopPropagation();
             e.preventDefault();
-            let x = e.clientX;
-            let y = e.clientY;
-            let docid = (e.target as any).DashDocId;
-            let tab = (e.target as any).parentElement as HTMLElement;
+            const x = e.clientX;
+            const y = e.clientY;
+            const docid = (e.target as any).DashDocId;
+            const tab = (e.target as any).parentElement as HTMLElement;
             DocServer.GetRefField(docid).then(action(async (sourceDoc: Opt<Field>) =>
                 (sourceDoc instanceof Doc) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
         }
@@ -352,18 +352,18 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
 
     updateDataField = async (json: string) => {
-        let matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
-        let docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", ""));
+        const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+        const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", ""));
 
         if (docids) {
-            let docs = (await Promise.all(docids.map(id => DocServer.GetRefField(id)))).filter(f => f).map(f => f as Doc);
+            const docs = (await Promise.all(docids.map(id => DocServer.GetRefField(id)))).filter(f => f).map(f => f as Doc);
             Doc.GetProto(this.props.Document)[this.props.fieldKey] = new List<Doc>(docs);
         }
     }
 
     @undoBatch
     stateChanged = () => {
-        var json = JSON.stringify(this._goldenLayout.toConfig());
+        const json = JSON.stringify(this._goldenLayout.toConfig());
         this.props.Document.dockingConfig = json;
         this.updateDataField(json);
 
@@ -380,7 +380,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     }
 
     htmlToElement(html: string) {
-        var template = document.createElement('template');
+        const template = document.createElement('template');
         html = html.trim(); // Never return a text node of whitespace as the result
         template.innerHTML = html;
         return template.content.firstChild;
@@ -392,24 +392,24 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 tab.contentItem.parent.config.fixed = true;
             }
 
-            let doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
-            let dataDoc = await DocServer.GetRefField(tab.contentItem.config.props.dataDocumentId) as Doc;
+            const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
+            const dataDoc = await DocServer.GetRefField(tab.contentItem.config.props.dataDocumentId) as Doc;
             if (doc instanceof Doc) {
-                let dragSpan = document.createElement("span");
+                const dragSpan = document.createElement("span");
                 dragSpan.style.position = "relative";
                 dragSpan.style.bottom = "6px";
                 dragSpan.style.paddingLeft = "4px";
                 dragSpan.style.paddingRight = "2px";
-                let gearSpan = document.createElement("span");
+                const gearSpan = document.createElement("span");
                 gearSpan.style.position = "relative";
                 gearSpan.style.paddingLeft = "0px";
                 gearSpan.style.paddingRight = "12px";
-                let upDiv = document.createElement("span");
+                const upDiv = document.createElement("span");
                 const stack = tab.contentItem.parent;
                 // shifts the focus to this tab when another tab is dragged over it
                 tab.element[0].onmouseenter = (e: any) => {
                     if (!this._isPointerDown || !SelectionManager.GetIsDragging()) return;
-                    var activeContentItem = tab.header.parent.getActiveContentItem();
+                    const activeContentItem = tab.header.parent.getActiveContentItem();
                     if (tab.contentItem !== activeContentItem) {
                         tab.header.parent.setActiveContentItem(tab.contentItem);
                     }
@@ -447,12 +447,12 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         tab.closeElement.off('click') //unbind the current click handler
             .click(async function () {
                 tab.reactionDisposer && tab.reactionDisposer();
-                let doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId);
+                const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId);
                 if (doc instanceof Doc) {
-                    let theDoc = doc;
+                    const theDoc = doc;
                     CollectionDockingView.Instance._removedDocs.push(theDoc);
 
-                    let userDoc = CurrentUserUtils.UserDocument;
+                    const userDoc = CurrentUserUtils.UserDocument;
                     let recent: Doc | undefined;
                     if (userDoc && (recent = await Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc))) {
                         Doc.AddDocToList(recent, "data", doc, undefined, true, true);
@@ -489,13 +489,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
                 stack.remove();
                 stack.contentItems.forEach(async (contentItem: any) => {
-                    let doc = await DocServer.GetRefField(contentItem.config.props.documentId);
+                    const doc = await DocServer.GetRefField(contentItem.config.props.documentId);
                     if (doc instanceof Doc) {
                         let recent: Doc | undefined;
                         if (CurrentUserUtils.UserDocument && (recent = await Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc))) {
                             Doc.AddDocToList(recent, "data", doc, undefined, true, true);
                         }
-                        let theDoc = doc;
+                        const theDoc = doc;
                         CollectionDockingView.Instance._removedDocs.push(theDoc);
                     }
                 });
@@ -505,7 +505,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             .off('click') //unbind the current click handler
             .click(action(function () {
                 stack.config.fixed = !stack.config.fixed;
-                // var url = Utils.prepend("/doc/" + stack.contentItems[0].tab.contentItem.config.props.documentId);
+                // const url = Utils.prepend("/doc/" + stack.contentItems[0].tab.contentItem.config.props.documentId);
                 // let win = window.open(url, stack.contentItems[0].tab.title, "width=300,height=400");
             }));
     }
@@ -563,9 +563,9 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     @action
     public PinDoc(doc: Doc) {
         //add this new doc to props.Document
-        let curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
+        const curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
         if (curPres) {
-            let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
+            const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
             Doc.GetProto(pinDoc).presentationTargetDoc = doc;
             Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
             const data = Cast(curPres.data, listSpec(Doc));
@@ -581,8 +581,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     }
 
     componentDidMount() {
-        let observer = new _global.ResizeObserver(action((entries: any) => {
-            for (let entry of entries) {
+        const observer = new _global.ResizeObserver(action((entries: any) => {
+            for (const entry of entries) {
                 this._panelWidth = entry.contentRect.width;
                 this._panelHeight = entry.contentRect.height;
             }
@@ -625,14 +625,14 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         const nativeH = this.nativeHeight();
         const nativeW = this.nativeWidth();
         if (!nativeW || !nativeH) return 1;
-        let wscale = this.panelWidth() / nativeW;
+        const wscale = this.panelWidth() / nativeW;
         return wscale * nativeH > this._panelHeight ? this._panelHeight / nativeH : wscale;
     }
 
     ScreenToLocalTransform = () => {
         if (this._mainCont && this._mainCont.children) {
-            let { scale, translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0].firstChild as HTMLElement);
-            scale = Utils.GetScreenTransform(this._mainCont).scale;
+            const { translateX, translateY } = Utils.GetScreenTransform(this._mainCont.children[0].firstChild as HTMLElement);
+            const scale = Utils.GetScreenTransform(this._mainCont).scale;
             return CollectionDockingView.Instance.props.ScreenToLocalTransform().translate(-translateX, -translateY).scale(1 / this.contentScaling() / scale);
         }
         return Transform.Identity();
@@ -657,7 +657,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     @computed get docView() {
         if (!this._document) return (null);
         const document = this._document;
-        let resolvedDataDoc = document.layout instanceof Doc ? document : this._dataDoc;
+        const resolvedDataDoc = document.layout instanceof Doc ? document : this._dataDoc;
         return <DocumentView key={document[Id]}
             Document={document}
             DataDoc={resolvedDataDoc}
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index df4b00b3a..d697e721b 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -64,9 +64,9 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         if (this._collapsed) {
             this.props.setDocHeight(this._heading, 20);
         } else {
-            let rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
-            let transformScale = this.props.screenToLocalTransform().Scale;
-            let trueHeight = rawHeight * transformScale;
+            const rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
+            const transformScale = this.props.screenToLocalTransform().Scale;
+            const trueHeight = rawHeight * transformScale;
             this.props.setDocHeight(this._heading, trueHeight);
         }
     }
@@ -77,8 +77,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         if (de.data instanceof DragManager.DocumentDragData) {
             (this.props.parent.Document.dropConverter instanceof ScriptField) &&
                 this.props.parent.Document.dropConverter.script.run({ dragData: de.data });
-            let key = StrCast(this.props.parent.props.Document.sectionFilter);
-            let castedValue = this.getValue(this._heading);
+            const key = StrCast(this.props.parent.props.Document.sectionFilter);
+            const castedValue = this.getValue(this._heading);
             de.data.droppedDocuments.forEach(d => d[key] = castedValue);
             this.props.parent.drop(e, de);
             e.stopPropagation();
@@ -86,7 +86,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     });
 
     getValue = (value: string): any => {
-        let parsed = parseInt(value);
+        const parsed = parseInt(value);
         if (!isNaN(parsed)) return parsed;
         if (value.toLowerCase().indexOf("true") > -1) return true;
         if (value.toLowerCase().indexOf("false") > -1) return false;
@@ -96,8 +96,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let castedValue = this.getValue(value);
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const castedValue = this.getValue(value);
         if (castedValue) {
             if (this.props.parent.sectionHeaders) {
                 if (this.props.parent.sectionHeaders.map(i => i.heading).indexOf(castedValue.toString()) > -1) {
@@ -135,18 +135,18 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @action
     addDocument = (value: string, shiftDown?: boolean) => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
         newDoc[key] = this.getValue(this.props.heading);
         return this.props.parent.props.addDocument(newDoc);
     }
 
     deleteRow = undoBatch(action(() => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
         this.props.docList.forEach(d => d[key] = undefined);
         if (this.props.parent.sectionHeaders && this.props.headingObject) {
-            let index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
+            const index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
             this.props.parent.sectionHeaders.splice(index, 1);
         }
     }));
@@ -162,18 +162,18 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     startDrag = (e: PointerEvent) => {
-        let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+        const [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
-            let alias = Doc.MakeAlias(this.props.parent.props.Document);
-            let key = StrCast(this.props.parent.props.Document.sectionFilter);
+            const alias = Doc.MakeAlias(this.props.parent.props.Document);
+            const key = StrCast(this.props.parent.props.Document.sectionFilter);
             let value = this.getValue(this._heading);
             value = typeof value === "string" ? `"${value}"` : value;
-            let script = `return doc.${key} === ${value}`;
-            let compiled = CompileScript(script, { params: { doc: Doc.name } });
+            const script = `return doc.${key} === ${value}`;
+            const compiled = CompileScript(script, { params: { doc: Doc.name } });
             if (compiled.compiled) {
-                let scriptField = new ScriptField(compiled);
+                const scriptField = new ScriptField(compiled);
                 alias.viewSpecScript = scriptField;
-                let dragData = new DragManager.DocumentDragData([alias]);
+                const dragData = new DragManager.DocumentDragData([alias]);
                 DragManager.StartDocumentDrag([this._headerRef.current!], dragData, e.clientX, e.clientY);
             }
 
@@ -196,7 +196,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         e.stopPropagation();
         e.preventDefault();
 
-        let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
+        const [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
         if (this._createAliasSelected) {
@@ -209,17 +209,17 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     renderColorPicker = () => {
-        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+        const selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
 
-        let pink = PastelSchemaPalette.get("pink2");
-        let purple = PastelSchemaPalette.get("purple4");
-        let blue = PastelSchemaPalette.get("bluegreen1");
-        let yellow = PastelSchemaPalette.get("yellow4");
-        let red = PastelSchemaPalette.get("red2");
-        let green = PastelSchemaPalette.get("bluegreen7");
-        let cyan = PastelSchemaPalette.get("bluegreen5");
-        let orange = PastelSchemaPalette.get("orange1");
-        let gray = "#f1efeb";
+        const pink = PastelSchemaPalette.get("pink2");
+        const purple = PastelSchemaPalette.get("purple4");
+        const blue = PastelSchemaPalette.get("bluegreen1");
+        const yellow = PastelSchemaPalette.get("yellow4");
+        const red = PastelSchemaPalette.get("red2");
+        const green = PastelSchemaPalette.get("bluegreen7");
+        const cyan = PastelSchemaPalette.get("bluegreen5");
+        const orange = PastelSchemaPalette.get("orange1");
+        const gray = "#f1efeb";
 
         return (
             <div className="collectionStackingView-colorPicker">
@@ -242,7 +242,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     toggleVisibility = action(() => this._collapsed = !this._collapsed);
 
     renderMenu = () => {
-        let selected = this._createAliasSelected;
+        const selected = this._createAliasSelected;
         return (<div className="collectionStackingView-optionPicker">
             <div className="optionOptions">
                 <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.toggleAlias}>Create Alias</div>
@@ -258,10 +258,10 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     @computed get contentLayout() {
-        let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
-        let style = this.props.parent; const collapsed = this._collapsed;
-        let chromeStatus = this.props.parent.props.Document.chromeStatus;
-        let newEditableViewProps = {
+        const rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
+        const style = this.props.parent; const collapsed = this._collapsed;
+        const chromeStatus = this.props.parent.props.Document.chromeStatus;
+        const newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
             contents: "+ NEW",
@@ -293,10 +293,10 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     @computed get headingView() {
-        let heading = this._heading;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
-        let headerEditableViewProps = {
+        const heading = this._heading;
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+        const headerEditableViewProps = {
             GetValue: () => evContents,
             SetValue: this.headingChanged,
             contents: evContents,
@@ -343,8 +343,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
     render() {
         const background = this._background; //to account for observables in Measure
-        let contentlayout = this.contentLayout;
-        let headingview = this.headingView;
+        const contentlayout = this.contentLayout;
+        const headingview = this.headingView;
         return <Measure offset onResize={this.handleResize}>
             {({ measureRef }) => {
                 return <div ref={measureRef}>
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 54a36f691..1700c14cf 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -1,7 +1,7 @@
 import React = require("react");
-import { action, computed, observable, trace, untracked, toJS } from "mobx";
+import { action, observable } from "mobx";
 import { observer } from "mobx-react";
-import ReactTable, { CellInfo, ComponentPropsGetterR, ReactTableDefaults, Column } from "react-table";
+import { CellInfo } from "react-table";
 import "react-table/react-table.css";
 import { emptyFunction, returnFalse, returnZero, returnOne } from "../../../Utils";
 import { Doc, DocListCast, DocListCastAsync, Field, Opt } from "../../../new_fields/Doc";
@@ -9,7 +9,7 @@ import { Id } from "../../../new_fields/FieldSymbols";
 import { SetupDrag, DragManager } from "../../util/DragManager";
 import { CompileScript } from "../../util/Scripting";
 import { Transform } from "../../util/Transform";
-import { COLLECTION_BORDER_WIDTH, MAX_ROW_HEIGHT } from '../globalCssVariables.scss';
+import { MAX_ROW_HEIGHT } from '../globalCssVariables.scss';
 import '../DocumentDecorations.scss';
 import { EditableView } from "../EditableView";
 import { FieldView, FieldViewProps } from "../nodes/FieldView";
@@ -89,8 +89,8 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         // this._isEditing = true;
         // this.props.setIsEditing(true);
 
-        let field = this.props.rowProps.original[this.props.rowProps.column.id!];
-        let doc = FieldValue(Cast(field, Doc));
+        const field = this.props.rowProps.original[this.props.rowProps.column.id!];
+        const doc = FieldValue(Cast(field, Doc));
         if (typeof field === "object" && doc) this.props.setPreviewDoc(doc);
     }
 
@@ -106,12 +106,12 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
 
     private drop = (e: Event, de: DragManager.DropEvent) => {
         if (de.data instanceof DragManager.DocumentDragData) {
-            let fieldKey = this.props.rowProps.column.id as string;
+            const fieldKey = this.props.rowProps.column.id as string;
             if (de.data.draggedDocuments.length === 1) {
                 this._document[fieldKey] = de.data.draggedDocuments[0];
             }
             else {
-                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.data.draggedDocuments, {});
+                const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.data.draggedDocuments, {});
                 this._document[fieldKey] = coll;
             }
             e.stopPropagation();
@@ -138,9 +138,9 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     // }
 
     renderCellWithType(type: string | undefined) {
-        let dragRef: React.RefObject<HTMLDivElement> = React.createRef();
+        const dragRef: React.RefObject<HTMLDivElement> = React.createRef();
 
-        let props: FieldViewProps = {
+        const props: FieldViewProps = {
             Document: this.props.rowProps.original,
             DataDoc: this.props.rowProps.original,
             fieldKey: this.props.rowProps.column.id as string,
@@ -161,23 +161,23 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             ContentScaling: returnOne
         };
 
-        let field = props.Document[props.fieldKey];
-        let doc = FieldValue(Cast(field, Doc));
-        let fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
+        const field = props.Document[props.fieldKey];
+        const doc = FieldValue(Cast(field, Doc));
+        const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
 
-        let onItemDown = (e: React.PointerEvent) => {
+        const onItemDown = (e: React.PointerEvent) => {
             if (fieldIsDoc) {
                 SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
                     this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument,
                     this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
             }
         };
-        let onPointerEnter = (e: React.PointerEvent): void => {
+        const onPointerEnter = (e: React.PointerEvent): void => {
             if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) {
                 dragRef.current!.className = "collectionSchemaView-cellContainer doc-drag-over";
             }
         };
-        let onPointerLeave = (e: React.PointerEvent): void => {
+        const onPointerLeave = (e: React.PointerEvent): void => {
             dragRef.current!.className = "collectionSchemaView-cellContainer";
         };
 
@@ -187,7 +187,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         if (type === "string") contents = typeof field === "string" ? (StrCast(field) === "" ? "--" : StrCast(field)) : "--" + typeof field + "--";
         if (type === "boolean") contents = typeof field === "boolean" ? (BoolCast(field) ? "true" : "false") : "--" + typeof field + "--";
         if (type === "document") {
-            let doc = FieldValue(Cast(field, Doc));
+            const doc = FieldValue(Cast(field, Doc));
             contents = typeof field === "object" ? doc ? StrCast(doc.title) === "" ? "--" : StrCast(doc.title) : `--${typeof field}--` : `--${typeof field}--`;
         }
 
@@ -215,7 +215,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                             height={"auto"}
                             maxHeight={Number(MAX_ROW_HEIGHT)}
                             GetValue={() => {
-                                let field = props.Document[props.fieldKey];
+                                const field = props.Document[props.fieldKey];
                                 if (Field.IsField(field)) {
                                     return Field.toScriptString(field);
                                 }
@@ -226,7 +226,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                                 if (value.startsWith(":=")) {
                                     return this.props.setComputed(value.substring(2), props.Document, this.props.rowProps.column.id!, this.props.row, this.props.col);
                                 }
-                                let script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
+                                const script = CompileScript(value, { requiredType: type, addReturn: true, params: { this: Doc.name, $r: "number", $c: "number", $: "any" } });
                                 if (!script.compiled) {
                                     return false;
                                 }
@@ -287,15 +287,15 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
     @action
     toggleChecked = (e: React.ChangeEvent<HTMLInputElement>) => {
         this._isChecked = e.target.checked;
-        let script = CompileScript(e.target.checked.toString(), { requiredType: "boolean", addReturn: true, params: { this: Doc.name } });
+        const script = CompileScript(e.target.checked.toString(), { requiredType: "boolean", addReturn: true, params: { this: Doc.name } });
         if (script.compiled) {
             this.applyToDoc(this._document, this.props.row, this.props.col, script.run);
         }
     }
 
     render() {
-        let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = (e: React.PointerEvent) => {
+        const reference = React.createRef<HTMLDivElement>();
+        const onItemDown = (e: React.PointerEvent) => {
             (!this.props.CollectionView || !this.props.CollectionView.props.isSelected() ? undefined :
                 SetupDrag(reference, () => this._document, this.props.moveDocument, this.props.Document.schemaDoc ? "copy" : undefined)(e));
         };
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index d24f63fbb..0114342b9 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, computed, observable, trace, untracked } from "mobx";
+import { action, observable } from "mobx";
 import { observer } from "mobx-react";
 import "./CollectionSchemaView.scss";
 import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes } from '@fortawesome/free-solid-svg-icons';
@@ -7,10 +7,8 @@ import { library, IconProp } from "@fortawesome/fontawesome-svg-core";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { Flyout, anchorPoints } from "../DocumentDecorations";
 import { ColumnType } from "./CollectionSchemaView";
-import { emptyFunction } from "../../../Utils";
-import { contains } from "typescript-collections/dist/lib/arrays";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
-import { SchemaHeaderField, RandomPastel, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
 
 library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile as any, faSortAmountDown, faSortAmountUp, faTimes);
@@ -32,7 +30,7 @@ export interface HeaderProps {
 
 export class CollectionSchemaHeader extends React.Component<HeaderProps> {
     render() {
-        let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" :
+        const icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" :
             this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify";
         return (
             <div className="collectionSchemaView-header" style={{ background: this.props.keyValue.color }}>
@@ -139,7 +137,7 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
     renderTypes = () => {
         if (this.props.typeConst) return <></>;
 
-        let type = this.props.columnField.type;
+        const type = this.props.columnField.type;
         return (
             <div className="collectionSchema-headerMenu-group">
                 <label>Column type:</label>
@@ -170,7 +168,7 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
     }
 
     renderSorting = () => {
-        let sort = this.props.columnField.desc;
+        const sort = this.props.columnField.desc;
         return (
             <div className="collectionSchema-headerMenu-group">
                 <label>Sort by:</label>
@@ -193,14 +191,14 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
     }
 
     renderColors = () => {
-        let selected = this.props.columnField.color;
+        const selected = this.props.columnField.color;
 
-        let pink = PastelSchemaPalette.get("pink2");
-        let purple = PastelSchemaPalette.get("purple2");
-        let blue = PastelSchemaPalette.get("bluegreen1");
-        let yellow = PastelSchemaPalette.get("yellow4");
-        let red = PastelSchemaPalette.get("red2");
-        let gray = "#f1efeb";
+        const pink = PastelSchemaPalette.get("pink2");
+        const purple = PastelSchemaPalette.get("purple2");
+        const blue = PastelSchemaPalette.get("bluegreen1");
+        const yellow = PastelSchemaPalette.get("yellow4");
+        const red = PastelSchemaPalette.get("red2");
+        const gray = "#f1efeb";
 
         return (
             <div className="collectionSchema-headerMenu-group">
@@ -291,8 +289,8 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
     @action
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
-            let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-            let exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
+            const keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+            const exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
                 this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
 
             if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
@@ -334,11 +332,11 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
     renderOptions = (): JSX.Element[] | JSX.Element => {
         if (!this._isOpen) return <></>;
 
-        let keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-        let exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
+        const keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+        const exactFound = keyOptions.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1 ||
             this.props.existingKeys.findIndex(key => key.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
 
-        let options = keyOptions.map(key => {
+        const options = keyOptions.map(key => {
             return <div key={key} className="key-option" onClick={() => { this.onSelect(key); this.setSearchTerm(""); }}>{key}</div>;
         });
 
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 274c8b6d1..90320df82 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -1,18 +1,18 @@
 import React = require("react");
-import { ReactTableDefaults, TableCellRenderer, ComponentPropsGetterR, ComponentPropsGetter0, RowInfo } from "react-table";
+import { ReactTableDefaults, TableCellRenderer, RowInfo } from "react-table";
 import "./CollectionSchemaView.scss";
 import { Transform } from "../../util/Transform";
 import { Doc } from "../../../new_fields/Doc";
 import { DragManager, SetupDrag } from "../../util/DragManager";
 import { SelectionManager } from "../../util/SelectionManager";
-import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
+import { Cast, FieldValue } from "../../../new_fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { action } from "mobx";
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { DocumentManager } from "../../util/DocumentManager";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
 
 library.add(faGripVertical, faTrash);
@@ -43,10 +43,10 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         document.removeEventListener("pointermove", this.onPointerMove);
     }
     onDragMove = (e: PointerEvent): void => {
-        let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
-        let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
-        let before = x[0] < bounds[0];
+        const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+        const rect = this._header!.current!.getBoundingClientRect();
+        const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+        const before = x[0] < bounds[0];
         this._header!.current!.className = "collectionSchema-col-wrapper";
         if (before) this._header!.current!.className += " col-before";
         if (!before) this._header!.current!.className += " col-after";
@@ -62,10 +62,10 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
 
     colDrop = (e: Event, de: DragManager.DropEvent) => {
         document.removeEventListener("pointermove", this.onDragMove, true);
-        let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
-        let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
-        let before = x[0] < bounds[0];
+        const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+        const rect = this._header!.current!.getBoundingClientRect();
+        const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
+        const before = x[0] < bounds[0];
         if (de.data instanceof DragManager.ColumnDragData) {
             this.props.reorderColumns(de.data.colKey, this.props.columnValue, before, this.props.allColumns);
             return true;
@@ -74,21 +74,21 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
     }
 
     onPointerMove = (e: PointerEvent) => {
-        let onRowMove = (e: PointerEvent) => {
+        const onRowMove = (e: PointerEvent) => {
             e.stopPropagation();
             e.preventDefault();
 
             document.removeEventListener("pointermove", onRowMove);
             document.removeEventListener('pointerup', onRowUp);
-            let dragData = new DragManager.ColumnDragData(this.props.columnValue);
+            const dragData = new DragManager.ColumnDragData(this.props.columnValue);
             DragManager.StartColumnDrag(this._dragRef.current!, dragData, e.x, e.y);
         };
-        let onRowUp = (): void => {
+        const onRowUp = (): void => {
             document.removeEventListener("pointermove", onRowMove);
             document.removeEventListener('pointerup', onRowUp);
         };
         if (e.buttons === 1) {
-            let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+            const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
             if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
                 document.removeEventListener("pointermove", this.onPointerMove);
                 e.stopPropagation();
@@ -106,14 +106,14 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
     @action
     onPointerDown = (e: React.PointerEvent, ref: React.RefObject<HTMLDivElement>) => {
         this._dragRef = ref;
-        let [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY);
+        const [dx, dy] = this.props.ScreenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
         document.addEventListener("pointermove", this.onPointerMove);
     }
 
 
     render() {
-        let reference = React.createRef<HTMLDivElement>();
+        const reference = React.createRef<HTMLDivElement>();
 
         return (
             <div className="collectionSchema-col" ref={this.createColDropTarget}>
@@ -152,10 +152,10 @@ export class MovableRow extends React.Component<MovableRowProps> {
         document.removeEventListener("pointermove", this.onDragMove, true);
     }
     onDragMove = (e: PointerEvent): void => {
-        let x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
-        let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
+        const x = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY);
+        const rect = this._header!.current!.getBoundingClientRect();
+        const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
+        const before = x[1] < bounds[1];
         this._header!.current!.className = "collectionSchema-row-wrapper";
         if (before) this._header!.current!.className += " row-above";
         if (!before) this._header!.current!.className += " row-below";
@@ -173,16 +173,16 @@ export class MovableRow extends React.Component<MovableRowProps> {
         const rowDoc = FieldValue(Cast(this.props.rowInfo.original, Doc));
         if (!rowDoc) return false;
 
-        let x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
-        let rect = this._header!.current!.getBoundingClientRect();
-        let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
-        let before = x[1] < bounds[1];
+        const x = this.props.ScreenToLocalTransform().transformPoint(de.x, de.y);
+        const rect = this._header!.current!.getBoundingClientRect();
+        const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
+        const before = x[1] < bounds[1];
 
         if (de.data instanceof DragManager.DocumentDragData) {
             e.stopPropagation();
             if (de.data.draggedDocuments[0] === rowDoc) return true;
-            let addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before);
-            let movedDocs = de.data.draggedDocuments;
+            const addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before);
+            const movedDocs = de.data.draggedDocuments;
             return (de.data.dropAction || de.data.userDropAction) ?
                 de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false)
                 : (de.data.moveDocument) ?
@@ -193,14 +193,14 @@ export class MovableRow extends React.Component<MovableRowProps> {
     }
 
     onRowContextMenu = (e: React.MouseEvent): void => {
-        let description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
+        const description = this.props.rowWrapped ? "Unwrap text on row" : "Text wrap row";
         ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
     }
 
     @undoBatch
     @action
     move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
-        let targetView = DocumentManager.Instance.getDocumentView(target);
+        const targetView = DocumentManager.Instance.getDocumentView(target);
         if (targetView && targetView.props.ContainingCollectionDoc) {
             return doc !== target && doc !== targetView.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc);
         }
@@ -217,8 +217,8 @@ export class MovableRow extends React.Component<MovableRowProps> {
         const doc = FieldValue(Cast(original, Doc));
         if (!doc) return <></>;
 
-        let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = SetupDrag(reference, () => doc, this.move);
+        const reference = React.createRef<HTMLDivElement>();
+        const onItemDown = SetupDrag(reference, () => doc, this.move);
 
         let className = "collectionSchema-row";
         if (this.props.rowFocused) className += " row-focused";
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 65856cad3..f336eaf75 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -94,11 +94,11 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     }
     @action
     onDividerMove = (e: PointerEvent): void => {
-        let nativeWidth = this._mainCont!.getBoundingClientRect();
-        let minWidth = 40;
-        let maxWidth = 1000;
-        let movedWidth = this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0];
-        let width = movedWidth < minWidth ? minWidth : movedWidth > maxWidth ? maxWidth : movedWidth;
+        const nativeWidth = this._mainCont!.getBoundingClientRect();
+        const minWidth = 40;
+        const maxWidth = 1000;
+        const movedWidth = this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0];
+        const width = movedWidth < minWidth ? minWidth : movedWidth > maxWidth ? maxWidth : movedWidth;
         this.props.Document.schemaPreviewWidth = width;
     }
     @action
@@ -136,7 +136,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
     @computed
     get previewPanel() {
-        let layoutDoc = this.previewDocument ? Doc.expandTemplateLayout(this.previewDocument, this.props.DataDoc) : undefined;
+        const layoutDoc = this.previewDocument ? Doc.expandTemplateLayout(this.previewDocument, this.props.DataDoc) : undefined;
         return <div ref={this.createTarget}>
             <ContentFittingDocumentView
                 Document={layoutDoc}
@@ -258,11 +258,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @computed get childDocs() {
         if (this.props.childDocs) return this.props.childDocs;
 
-        let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
+        const doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
         return DocListCast(doc[this.props.fieldKey]);
     }
     set childDocs(docs: Doc[]) {
-        let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
+        const doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
         doc[this.props.fieldKey] = new List<Doc>(docs);
     }
 
@@ -288,12 +288,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
-        let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
-        let columns: Column<Doc>[] = [];
-        let tableIsFocused = this.props.isFocused(this.props.Document);
-        let focusedRow = this._focusedCell.row;
-        let focusedCol = this._focusedCell.col;
-        let isEditable = !this._headerIsEditing;
+        const possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
+        const columns: Column<Doc>[] = [];
+        const tableIsFocused = this.props.isFocused(this.props.Document);
+        const focusedRow = this._focusedCell.row;
+        const focusedCol = this._focusedCell.col;
+        const isEditable = !this._headerIsEditing;
 
         if (this.childDocs.reduce((found, doc) => found || doc.type === "collection", false)) {
             columns.push(
@@ -313,8 +313,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             );
         }
 
-        let cols = this.columns.map(col => {
-            let header = <CollectionSchemaHeader
+        const cols = this.columns.map(col => {
+            const header = <CollectionSchemaHeader
                 keyValue={col}
                 possibleKeys={possibleKeys}
                 existingKeys={this.columns.map(c => c.heading)}
@@ -333,11 +333,11 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 accessor: (doc: Doc) => doc ? doc[col.heading] : 0,
                 id: col.heading,
                 Cell: (rowProps: CellInfo) => {
-                    let rowIndex = rowProps.index;
-                    let columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!);
-                    let isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused;
+                    const rowIndex = rowProps.index;
+                    const columnIndex = this.columns.map(c => c.heading).indexOf(rowProps.column.id!);
+                    const isFocused = focusedRow === rowIndex && focusedCol === columnIndex && tableIsFocused;
 
-                    let props: CellProps = {
+                    const props: CellProps = {
                         row: rowIndex,
                         col: columnIndex,
                         rowProps: rowProps,
@@ -358,7 +358,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         getField: this.getField,
                     };
 
-                    let colType = this.getColumnType(col);
+                    const colType = this.getColumnType(col);
                     if (colType === ColumnType.Number) return <CollectionSchemaNumberCell {...props} />;
                     if (colType === ColumnType.String) return <CollectionSchemaStringCell {...props} />;
                     if (colType === ColumnType.Boolean) return <CollectionSchemaCheckboxCell {...props} />;
@@ -384,9 +384,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     constructor(props: SchemaTableProps) {
         super(props);
         // convert old schema columns (list of strings) into new schema columns (list of schema header fields)
-        let oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []);
+        const oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []);
         if (oldSchemaColumns && oldSchemaColumns.length && typeof oldSchemaColumns[0] !== "object") {
-            let newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
+            const newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
             this.props.Document.schemaColumns = new List<SchemaHeaderField>(newSchemaColumns);
         }
     }
@@ -418,10 +418,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     private getTdProps: ComponentPropsGetterR = (state, rowInfo, column, instance) => {
         if (!rowInfo || column) return {};
 
-        let row = rowInfo.index;
+        const row = rowInfo.index;
         //@ts-ignore
-        let col = this.columns.map(c => c.heading).indexOf(column!.id);
-        let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
+        const col = this.columns.map(c => c.heading).indexOf(column!.id);
+        const isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
         // TODO: editing border doesn't work :(
         return {
             style: {
@@ -432,7 +432,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     onCloseCollection = (collection: Doc): void => {
-        let index = this._openCollections.findIndex(col => col === collection[Id]);
+        const index = this._openCollections.findIndex(col => col === collection[Id]);
         if (index > -1) this._openCollections.splice(index, 1);
     }
 
@@ -450,7 +450,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @action
     onKeyDown = (e: KeyboardEvent): void => {
         if (!this._cellIsEditing && !this._headerIsEditing && this.props.isFocused(this.props.Document)) {// && this.props.isSelected(true)) {
-            let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
+            const direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this._focusedCell = this.changeFocusedCellByDirection(direction, this._focusedCell.row, this._focusedCell.col);
 
             const pdoc = FieldValue(this.childDocs[this._focusedCell.row]);
@@ -479,7 +479,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @undoBatch
     createRow = () => {
-        let newDoc = Docs.Create.TextDocument({ title: "", width: 100, height: 30 });
+        const newDoc = Docs.Create.TextDocument({ title: "", width: 100, height: 30 });
         this.props.addDocument(newDoc);
     }
 
@@ -498,7 +498,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @undoBatch
     @action
     deleteColumn = (key: string) => {
-        let columns = this.columns;
+        const columns = this.columns;
         if (columns === undefined) {
             this.columns = new List<SchemaHeaderField>([]);
         } else {
@@ -513,7 +513,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @undoBatch
     @action
     changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
-        let columns = this.columns;
+        const columns = this.columns;
         if (columns === undefined) {
             this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
         } else {
@@ -523,7 +523,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             } else {
                 const index = columns.map(c => c.heading).indexOf(oldKey);
                 if (index > -1) {
-                    let column = columns[index];
+                    const column = columns[index];
                     column.setHeading(newKey);
                     columns[index] = column;
                     this.columns = columns;
@@ -554,8 +554,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
         if (columnTypes.get(columnField.heading)) return;
 
-        let columns = this.columns;
-        let index = columns.indexOf(columnField);
+        const columns = this.columns;
+        const index = columns.indexOf(columnField);
         if (index > -1) {
             columnField.setType(NumCast(type));
             columns[index] = columnField;
@@ -575,8 +575,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @undoBatch
     setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
-        let columns = this.columns;
-        let index = columns.indexOf(columnField);
+        const columns = this.columns;
+        const index = columns.indexOf(columnField);
         if (index > -1) {
             columnField.setColor(color);
             columns[index] = columnField;
@@ -589,10 +589,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @undoBatch
     reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
-        let columns = [...columnsValues];
-        let oldIndex = columns.indexOf(toMove);
-        let relIndex = columns.indexOf(relativeTo);
-        let newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex;
+        const columns = [...columnsValues];
+        const oldIndex = columns.indexOf(toMove);
+        const relIndex = columns.indexOf(relativeTo);
+        const newIndex = (oldIndex > relIndex && !before) ? relIndex + 1 : (oldIndex < relIndex && before) ? relIndex - 1 : relIndex;
 
         if (oldIndex === newIndex) return;
 
@@ -603,17 +603,17 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @undoBatch
     @action
     setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
-        let columns = this.columns;
-        let index = columns.findIndex(c => c.heading === columnField.heading);
-        let column = columns[index];
+        const columns = this.columns;
+        const index = columns.findIndex(c => c.heading === columnField.heading);
+        const column = columns[index];
         column.setDesc(descending);
         columns[index] = column;
         this.columns = columns;
     }
 
     get documentKeys() {
-        let docs = this.childDocs;
-        let keys: { [key: string]: boolean } = {};
+        const docs = this.childDocs;
+        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.
@@ -628,8 +628,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     toggleTextWrapRow = (doc: Doc): void => {
-        let textWrapped = this.textWrappedRows;
-        let index = textWrapped.findIndex(id => doc[Id] === id);
+        const textWrapped = this.textWrappedRows;
+        const index = textWrapped.findIndex(id => doc[Id] === id);
 
         index > -1 ? textWrapped.splice(index, 1) : textWrapped.push(doc[Id]);
 
@@ -638,10 +638,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @computed
     get reactTable() {
-        let children = this.childDocs;
-        let hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false);
-        let expandedRowsList = this._openCollections.map(col => children.findIndex(doc => doc[Id] === col).toString());
-        let expanded = {};
+        const children = this.childDocs;
+        const hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false);
+        const expandedRowsList = this._openCollections.map(col => children.findIndex(doc => doc[Id] === col).toString());
+        const expanded = {};
         //@ts-ignore
         expandedRowsList.forEach(row => expanded[row] = true);
         console.log("text wrapped rows", ...[...this.textWrappedRows]); // TODO: get component to rerender on text wrap change without needign to console.log :((((
@@ -668,10 +668,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     onResizedChange = (newResized: Resize[], event: any) => {
-        let columns = this.columns;
+        const columns = this.columns;
         newResized.forEach(resized => {
-            let index = columns.findIndex(c => c.heading === resized.id);
-            let column = columns[index];
+            const index = columns.findIndex(c => c.heading === resized.id);
+            const column = columns[index];
             column.setWidth(resized.value);
             columns[index] = column;
         });
@@ -688,16 +688,16 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     makeDB = async () => {
         let csv: string = this.columns.reduce((val, col) => val + col + ",", "");
         csv = csv.substr(0, csv.length - 1) + "\n";
-        let self = this;
+        const self = this;
         this.childDocs.map(doc => {
             csv += self.columns.reduce((val, col) => val + (doc[col.heading] ? doc[col.heading]!.toString() : "0") + ",", "");
             csv = csv.substr(0, csv.length - 1) + "\n";
         });
         csv.substring(0, csv.length - 1);
-        let dbName = StrCast(this.props.Document.title);
-        let res = await Gateway.Instance.PostSchema(csv, dbName);
+        const dbName = StrCast(this.props.Document.title);
+        const res = await Gateway.Instance.PostSchema(csv, dbName);
         if (self.props.CollectionView && self.props.CollectionView.props.addDocument) {
-            let schemaDoc = await Docs.Create.DBDocument("https://www.cs.brown.edu/" + dbName, { title: dbName }, { dbDoc: self.props.Document });
+            const schemaDoc = await Docs.Create.DBDocument("https://www.cs.brown.edu/" + dbName, { title: dbName }, { dbDoc: self.props.Document });
             if (schemaDoc) {
                 //self.props.CollectionView.props.addDocument(schemaDoc, false);
                 self.props.Document.schemaDoc = schemaDoc;
@@ -706,7 +706,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     getField = (row: number, col?: number) => {
-        let docs = this.childDocs;
+        const docs = this.childDocs;
 
         row = row % docs.length;
         while (row < 0) row += docs.length;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e564f1193..955fcda80 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -1,7 +1,7 @@
 import React = require("react");
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { CursorProperty } from "csstype";
-import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import Switch from 'rc-switch';
 import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
@@ -10,7 +10,7 @@ import { List } from "../../../new_fields/List";
 import { listSpec } from "../../../new_fields/Schema";
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from "../../../new_fields/Types";
-import { emptyFunction, Utils, numberRange } from "../../../Utils";
+import { emptyFunction, Utils } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DragManager } from "../../util/DragManager";
 import { Transform } from "../../util/Transform";
@@ -56,15 +56,15 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     children(docs: Doc[]) {
         this._docXfs.length = 0;
         return docs.map((d, i) => {
-            let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
-            let layoutDoc = pair.layout ? Doc.Layout(pair.layout) : d;
-            let width = () => Math.min(layoutDoc.nativeWidth && !layoutDoc.ignoreAspect && !this.props.Document.fillColumn ? layoutDoc[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
-            let height = () => this.getDocHeight(layoutDoc);
-            let dref = React.createRef<HTMLDivElement>();
-            let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
+            const pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
+            const layoutDoc = pair.layout ? Doc.Layout(pair.layout) : d;
+            const width = () => Math.min(layoutDoc.nativeWidth && !layoutDoc.ignoreAspect && !this.props.Document.fillColumn ? layoutDoc[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
+            const height = () => this.getDocHeight(layoutDoc);
+            const dref = React.createRef<HTMLDivElement>();
+            const dxf = () => this.getDocTransform(layoutDoc, dref.current!);
             this._docXfs.push({ dxf: dxf, width: width, height: height });
-            let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
-            let style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
+            const style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
                 {this.getDisplayDoc(pair.layout || d, pair.data, dxf, width)}
             </div>;
@@ -83,20 +83,20 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             return new Map<SchemaHeaderField, Doc[]>();
         }
         const sectionHeaders = this.sectionHeaders;
-        let fields = new Map<SchemaHeaderField, Doc[]>(sectionHeaders.map(sh => [sh, []] as [SchemaHeaderField, []]));
+        const fields = new Map<SchemaHeaderField, Doc[]>(sectionHeaders.map(sh => [sh, []] as [SchemaHeaderField, []]));
         this.filteredChildren.map(d => {
-            let sectionValue = (d[this.sectionFilter] ? d[this.sectionFilter] : `NO ${this.sectionFilter.toUpperCase()} VALUE`) as object;
+            const sectionValue = (d[this.sectionFilter] ? d[this.sectionFilter] : `NO ${this.sectionFilter.toUpperCase()} VALUE`) as object;
             // the next five lines ensures that floating point rounding errors don't create more than one section -syip
-            let parsed = parseInt(sectionValue.toString());
-            let castedSectionValue = !isNaN(parsed) ? parsed : sectionValue;
+            const parsed = parseInt(sectionValue.toString());
+            const castedSectionValue = !isNaN(parsed) ? parsed : sectionValue;
 
             // look for if header exists already
-            let existingHeader = sectionHeaders.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${this.sectionFilter.toUpperCase()} VALUE`));
+            const existingHeader = sectionHeaders.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${this.sectionFilter.toUpperCase()} VALUE`));
             if (existingHeader) {
                 fields.get(existingHeader)!.push(d);
             }
             else {
-                let newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `NO ${this.sectionFilter.toUpperCase()} VALUE`);
+                const newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `NO ${this.sectionFilter.toUpperCase()} VALUE`);
                 fields.set(newSchemaHeader, [d]);
                 sectionHeaders.push(newSchemaHeader);
             }
@@ -108,26 +108,26 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         super.componentDidMount();
         this._heightDisposer = reaction(() => {
             if (this.props.Document.autoHeight) {
-                let sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
+                const sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
                 if (this.isStackingView) {
-                    let res = this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => {
-                        let r1 = Math.max(maxHght,
+                    const res = this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => {
+                        const r1 = Math.max(maxHght,
                             (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => {
-                                let val = height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap);
+                                const val = height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap);
                                 return val;
                             }, this.yMargin));
                         return r1;
                     }, 0);
                     return res;
                 } else {
-                    let sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0);
+                    const sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0);
                     return this.props.ContentScaling() * (sum + (this.Sections.size ? (this.props.Document.miniHeaders ? 20 : 85) : -15));
                 }
             }
             return -1;
         },
             (hgt: number) => {
-                let doc = hgt === -1 ? undefined : this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
+                const doc = hgt === -1 ? undefined : this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
                 doc && hgt > 0 && (Doc.Layout(doc).height = hgt);
             },
             { fireImmediately: true }
@@ -162,9 +162,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get onClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
     getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
-        let layoutDoc = Doc.Layout(doc);
-        let height = () => this.getDocHeight(doc);
-        let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
+        const layoutDoc = Doc.Layout(doc);
+        const height = () => this.getDocHeight(doc);
+        const finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
         return <ContentFittingDocumentView
             Document={doc}
             DataDocument={dataDoc}
@@ -192,12 +192,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     getDocHeight(d?: Doc) {
         if (!d) return 0;
-        let layoutDoc = Doc.Layout(d);
-        let nw = NumCast(layoutDoc.nativeWidth);
-        let nh = NumCast(layoutDoc.nativeHeight);
+        const layoutDoc = Doc.Layout(d);
+        const nw = NumCast(layoutDoc.nativeWidth);
+        const nh = NumCast(layoutDoc.nativeHeight);
         let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
         if (!layoutDoc.ignoreAspect && !layoutDoc.fitWidth && nw && nh) {
-            let aspect = nw && nh ? nh / nw : 1;
+            const aspect = nw && nh ? nh / nw : 1;
             if (!(d.nativeWidth && !layoutDoc.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(layoutDoc[WidthSym](), wid);
             return wid * aspect;
         }
@@ -215,8 +215,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     @action
     onDividerMove = (e: PointerEvent): void => {
-        let dragPos = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
-        let delta = dragPos - this._columnStart;
+        const dragPos = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
+        const delta = dragPos - this._columnStart;
         this._columnStart = dragPos;
         this.layoutDoc.columnWidth = Math.max(10, this.columnWidth + delta);
     }
@@ -238,13 +238,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        let where = [de.x, de.y];
+        const where = [de.x, de.y];
         let targInd = -1;
         let plusOne = false;
         if (de.data instanceof DragManager.DocumentDragData) {
             this._docXfs.map((cd, i) => {
-                let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
-                let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
+                const pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+                const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
                 if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
                     targInd = i;
                     plusOne = (where[1] > (pos[1] + pos1[1]) / 2 ? 1 : 0) ? true : false;
@@ -252,12 +252,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             });
         }
         if (super.drop(e, de)) {
-            let newDoc = de.data.droppedDocuments[0];
-            let docs = this.childDocList;
+            const newDoc = de.data.droppedDocuments[0];
+            const docs = this.childDocList;
             if (docs) {
                 if (targInd === -1) targInd = docs.length;
                 else targInd = docs.indexOf(this.filteredChildren[targInd]);
-                let srcInd = docs.indexOf(newDoc);
+                const srcInd = docs.indexOf(newDoc);
                 docs.splice(srcInd, 1);
                 docs.splice((targInd > srcInd ? targInd - 1 : targInd) + (plusOne ? 1 : 0), 0, newDoc);
             }
@@ -267,19 +267,19 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @undoBatch
     @action
     onDrop = async (e: React.DragEvent): Promise<void> => {
-        let where = [e.clientX, e.clientY];
+        const where = [e.clientX, e.clientY];
         let targInd = -1;
         this._docXfs.map((cd, i) => {
-            let pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
-            let pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
+            const pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+            const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
             if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
                 targInd = i;
             }
         });
         super.onDrop(e, {}, () => {
             if (targInd !== -1) {
-                let newDoc = this.childDocs[this.childDocs.length - 1];
-                let docs = this.childDocList;
+                const newDoc = this.childDocs[this.childDocs.length - 1];
+                const docs = this.childDocList;
                 if (docs) {
                     docs.splice(docs.length - 1, 1);
                     docs.splice(targInd, 0, newDoc);
@@ -289,13 +289,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     headings = () => Array.from(this.Sections.keys());
     sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
-        let key = this.sectionFilter;
+        const key = this.sectionFilter;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
-        let types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
+        const types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
         if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
             type = types[0];
         }
-        let cols = () => this.isStackingView ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
+        const cols = () => this.isStackingView ? 1 : Math.max(1, Math.min(this.filteredChildren.length,
             Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
         return <CollectionStackingViewFieldColumn
             key={heading ? heading.heading : ""}
@@ -313,23 +313,23 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     getDocTransform(doc: Doc, dref: HTMLDivElement) {
         if (!dref) return Transform.Identity();
-        let y = this._scroll; // required for document decorations to update when the text box container is scrolled
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
-        let outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
-        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+        const y = this._scroll; // required for document decorations to update when the text box container is scrolled
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
+        const outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
+        const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
         return this.props.ScreenToLocalTransform().
             translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0)).
             scale(NumCast(doc.width, 1) / this.columnWidth);
     }
 
     sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
-        let key = this.sectionFilter;
+        const key = this.sectionFilter;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
-        let types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
+        const types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
         if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
             type = types[0];
         }
-        let rows = () => !this.isStackingView ? 1 : Math.max(1, Math.min(docList.length,
+        const rows = () => !this.isStackingView ? 1 : Math.max(1, Math.min(docList.length,
             Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
         return <CollectionMasonryViewFieldRow
             key={heading ? heading.heading : ""}
@@ -356,9 +356,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
 
     sortFunc = (a: [SchemaHeaderField, Doc[]], b: [SchemaHeaderField, Doc[]]): 1 | -1 => {
-        let descending = BoolCast(this.props.Document.stackingHeadersSortDescending);
-        let firstEntry = descending ? b : a;
-        let secondEntry = descending ? a : b;
+        const descending = BoolCast(this.props.Document.stackingHeadersSortDescending);
+        const firstEntry = descending ? b : a;
+        const secondEntry = descending ? a : b;
         return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1;
     }
 
@@ -369,28 +369,28 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     onContextMenu = (e: React.MouseEvent): void => {
         // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
         if (!e.isPropagationStopped()) {
-            let subItems: ContextMenuProps[] = [];
+            const subItems: ContextMenuProps[] = [];
             subItems.push({ description: `${this.props.Document.fillColumn ? "Variable Size" : "Autosize"} Column`, event: () => this.props.Document.fillColumn = !this.props.Document.fillColumn, icon: "plus" });
             subItems.push({ description: `${this.props.Document.showTitles ? "Hide Titles" : "Show Titles"}`, event: () => this.props.Document.showTitles = !this.props.Document.showTitles ? "title" : "", icon: "plus" });
             subItems.push({ description: `${this.props.Document.showCaptions ? "Hide Captions" : "Show Captions"}`, event: () => this.props.Document.showCaptions = !this.props.Document.showCaptions ? "caption" : "", icon: "plus" });
             ContextMenu.Instance.addItem({ description: "Stacking Options ...", subitems: subItems, icon: "eye" });
 
-            let existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
-            let onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+            const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+            const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
             onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
             !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
         }
     }
 
     render() {
-        let editableViewProps = {
+        const editableViewProps = {
             GetValue: () => "",
             SetValue: this.addGroup,
             contents: "+ ADD A GROUP"
         };
         let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
         if (this.sectionFilter) {
-            let entries = Array.from(this.Sections.entries());
+            const entries = Array.from(this.Sections.entries());
             sections = entries.sort(this.sortFunc);
         }
         return (
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index b9d334b10..80dc482af 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -2,17 +2,14 @@ import React = require("react");
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, trace, runInAction } from "mobx";
+import { action, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, WidthSym } from "../../../new_fields/Doc";
-import { Id } from "../../../new_fields/FieldSymbols";
+import { Doc } from "../../../new_fields/Doc";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { NumCast, StrCast } from "../../../new_fields/Types";
-import { Utils } from "../../../Utils";
 import { Docs } from "../../documents/Documents";
 import { DragManager } from "../../util/DragManager";
-import { CompileScript } from "../../util/Scripting";
 import { SelectionManager } from "../../util/SelectionManager";
 import { Transform } from "../../util/Transform";
 import { undoBatch } from "../../util/UndoManager";
@@ -61,8 +58,8 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     columnDrop = action((e: Event, de: DragManager.DropEvent) => {
         this._createAliasSelected = false;
         if (de.data instanceof DragManager.DocumentDragData) {
-            let key = StrCast(this.props.parent.props.Document.sectionFilter);
-            let castedValue = this.getValue(this._heading);
+            const key = StrCast(this.props.parent.props.Document.sectionFilter);
+            const castedValue = this.getValue(this._heading);
             if (castedValue) {
                 de.data.droppedDocuments.forEach(d => d[key] = castedValue);
             }
@@ -74,7 +71,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         }
     });
     getValue = (value: string): any => {
-        let parsed = parseInt(value);
+        const parsed = parseInt(value);
         if (!isNaN(parsed)) {
             return parsed;
         }
@@ -90,8 +87,8 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let castedValue = this.getValue(value);
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const castedValue = this.getValue(value);
         if (castedValue) {
             if (this.props.parent.sectionHeaders) {
                 if (this.props.parent.sectionHeaders.map(i => i.heading).indexOf(castedValue.toString()) > -1) {
@@ -135,11 +132,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @action
     addDocument = (value: string, shiftDown?: boolean) => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, documentText: "@@@" + value, title: value, autoHeight: true });
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const newDoc = Docs.Create.TextDocument({ height: 18, width: 200, documentText: "@@@" + value, title: value, autoHeight: true });
         newDoc[key] = this.getValue(this.props.heading);
-        let maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
-        let heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
+        const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+        const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
         newDoc.heading = heading;
         return this.props.parent.props.addDocument(newDoc);
     }
@@ -147,10 +144,10 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @action
     deleteColumn = () => {
         this._createAliasSelected = false;
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
         this.props.docList.forEach(d => d[key] = undefined);
         if (this.props.parent.sectionHeaders && this.props.headingObject) {
-            let index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
+            const index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
             this.props.parent.sectionHeaders.splice(index, 1);
         }
     }
@@ -166,10 +163,10 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     startDrag = (e: PointerEvent) => {
-        let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+        const [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
-            let alias = Doc.MakeAlias(this.props.parent.props.Document);
-            let key = StrCast(this.props.parent.props.Document.sectionFilter);
+            const alias = Doc.MakeAlias(this.props.parent.props.Document);
+            const key = StrCast(this.props.parent.props.Document.sectionFilter);
             let value = this.getValue(this._heading);
             value = typeof value === "string" ? `"${value}"` : value;
             alias.viewSpecScript = ScriptField.MakeFunction(`doc.${key} === ${value}`, { doc: Doc.name });
@@ -195,7 +192,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         e.stopPropagation();
         e.preventDefault();
 
-        let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
+        const [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
         if (this._createAliasSelected) {
@@ -208,17 +205,17 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     renderColorPicker = () => {
-        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+        const selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
 
-        let pink = PastelSchemaPalette.get("pink2");
-        let purple = PastelSchemaPalette.get("purple4");
-        let blue = PastelSchemaPalette.get("bluegreen1");
-        let yellow = PastelSchemaPalette.get("yellow4");
-        let red = PastelSchemaPalette.get("red2");
-        let green = PastelSchemaPalette.get("bluegreen7");
-        let cyan = PastelSchemaPalette.get("bluegreen5");
-        let orange = PastelSchemaPalette.get("orange1");
-        let gray = "#f1efeb";
+        const pink = PastelSchemaPalette.get("pink2");
+        const purple = PastelSchemaPalette.get("purple4");
+        const blue = PastelSchemaPalette.get("bluegreen1");
+        const yellow = PastelSchemaPalette.get("yellow4");
+        const red = PastelSchemaPalette.get("red2");
+        const green = PastelSchemaPalette.get("bluegreen7");
+        const cyan = PastelSchemaPalette.get("bluegreen5");
+        const orange = PastelSchemaPalette.get("orange1");
+        const gray = "#f1efeb";
 
         return (
             <div className="collectionStackingView-colorPicker">
@@ -243,7 +240,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     renderMenu = () => {
-        let selected = this._createAliasSelected;
+        const selected = this._createAliasSelected;
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
@@ -262,16 +259,16 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @observable _headingsHack: number = 1;
 
     render() {
-        let cols = this.props.cols();
-        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        const cols = this.props.cols();
+        const key = StrCast(this.props.parent.props.Document.sectionFilter);
         let templatecols = "";
-        let headings = this.props.headings();
-        let heading = this._heading;
-        let style = this.props.parent;
-        let singleColumn = style.isStackingView;
-        let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
-        let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
-        let headerEditableViewProps = {
+        const headings = this.props.headings();
+        const heading = this._heading;
+        const style = this.props.parent;
+        const singleColumn = style.isStackingView;
+        const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
+        const evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+        const headerEditableViewProps = {
             GetValue: () => evContents,
             SetValue: this.headingChanged,
             contents: evContents,
@@ -281,7 +278,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             toggle: this.toggleVisibility,
             color: this._color
         };
-        let newEditableViewProps = {
+        const newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
             contents: "+ NEW",
@@ -290,7 +287,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             toggle: this.toggleVisibility,
             color: this._color
         };
-        let headingView = this.props.headingObject ?
+        const headingView = this.props.headingObject ?
             <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
                 style={{
                     width: (style.columnWidth) /
@@ -335,7 +332,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                 </div>
             </div> : (null);
         for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
-        let chromeStatus = this.props.parent.props.Document.chromeStatus;
+        const chromeStatus = this.props.parent.props.Document.chromeStatus;
         return (
             <div className="collectionStackingViewFieldColumn" key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
                 ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
diff --git a/src/client/views/collections/CollectionStaffView.tsx b/src/client/views/collections/CollectionStaffView.tsx
index 40e860b12..105061f46 100644
--- a/src/client/views/collections/CollectionStaffView.tsx
+++ b/src/client/views/collections/CollectionStaffView.tsx
@@ -2,7 +2,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import { Transform } from "../../util/Transform";
 import React = require("react");
 import { computed, action, IReactionDisposer, reaction, runInAction, observable } from "mobx";
-import { Doc, HeightSym } from "../../../new_fields/Doc";
+import { Doc } from "../../../new_fields/Doc";
 import { NumCast } from "../../../new_fields/Types";
 import "./CollectionStaffView.scss";
 import { observer } from "mobx-react";
@@ -32,9 +32,9 @@ export class CollectionStaffView extends CollectionSubView(doc => doc) {
     }
 
     @computed get staves() {
-        let staves = [];
+        const staves = [];
         for (let i = 0; i < this._staves; i++) {
-            let rows = [];
+            const rows = [];
             for (let j = 0; j < 5; j++) {
                 rows.push(<div key={`staff-${i}-${j}`} className="collectionStaffView-line"></div>);
             }
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index e80825825..0a2e27165 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -19,7 +19,7 @@ import { FieldViewProps } from "../nodes/FieldView";
 import { FormattedTextBox, GoogleRef } from "../nodes/FormattedTextBox";
 import { CollectionView } from "./CollectionView";
 import React = require("react");
-var path = require('path');
+import { basename } from 'path';
 import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
 import { Networking } from "../../Network";
@@ -92,7 +92,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             return Cast(this.dataField, listSpec(Doc));
         }
         get childDocs() {
-            let docs = DocListCast(this.dataField);
+            const docs = DocListCast(this.dataField);
             const viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
             return viewSpecScript ? docs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result) : docs;
         }
@@ -100,10 +100,10 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         @action
         protected async setCursorPosition(position: [number, number]) {
             let ind;
-            let doc = this.props.Document;
-            let id = CurrentUserUtils.id;
-            let email = Doc.CurrentUserEmail;
-            let pos = { x: position[0], y: position[1] };
+            const doc = this.props.Document;
+            const id = CurrentUserUtils.id;
+            const email = Doc.CurrentUserEmail;
+            const pos = { x: position[0], y: position[1] };
             if (id && email) {
                 const proto = Doc.GetProto(doc);
                 if (!proto) {
@@ -123,7 +123,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 if (cursors.length > 0 && (ind = cursors.findIndex(entry => entry.data.metadata.id === id)) > -1) {
                     cursors[ind].setPosition(pos);
                 } else {
-                    let entry = new CursorField({ metadata: { id: id, identifier: email, timestamp: Date.now() }, position: pos });
+                    const entry = new CursorField({ metadata: { id: id, identifier: email, timestamp: Date.now() }, position: pos });
                     cursors.push(entry);
                 }
             }
@@ -145,7 +145,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 if (de.data.dropAction || de.data.userDropAction) {
                     added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
                 } else if (de.data.moveDocument) {
-                    let movedDocs = de.data.draggedDocuments;
+                    const movedDocs = de.data.draggedDocuments;
                     added = movedDocs.reduce((added: boolean, d, i) =>
                         de.data.droppedDocuments[i] !== d ? this.props.addDocument(de.data.droppedDocuments[i]) :
                             de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false);
@@ -169,8 +169,8 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 e.stopPropagation(); // bcz: this is a hack to stop propagation when dropping an image on a text document with shift+ctrl
                 return;
             }
-            let html = e.dataTransfer.getData("text/html");
-            let text = e.dataTransfer.getData("text/plain");
+            const html = e.dataTransfer.getData("text/html");
+            const text = e.dataTransfer.getData("text/plain");
 
             if (text && text.startsWith("<div")) {
                 return;
@@ -179,9 +179,9 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             e.preventDefault();
 
             if (html && FormattedTextBox.IsFragment(html)) {
-                let href = FormattedTextBox.GetHref(html);
+                const href = FormattedTextBox.GetHref(html);
                 if (href) {
-                    let docid = FormattedTextBox.GetDocFromUrl(href);
+                    const docid = FormattedTextBox.GetDocFromUrl(href);
                     if (docid) { // prosemirror text containing link to dash document
                         DocServer.GetRefField(docid).then(f => {
                             if (f instanceof Doc) {
@@ -198,19 +198,19 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 return;
             }
             if (html && !html.startsWith("<a")) {
-                let tags = html.split("<");
+                const tags = html.split("<");
                 if (tags[0] === "") tags.splice(0, 1);
-                let img = tags[0].startsWith("img") ? tags[0] : tags.length > 1 && tags[1].startsWith("img") ? tags[1] : "";
+                const img = tags[0].startsWith("img") ? tags[0] : tags.length > 1 && tags[1].startsWith("img") ? tags[1] : "";
                 if (img) {
-                    let split = img.split("src=\"")[1].split("\"")[0];
-                    let doc = Docs.Create.ImageDocument(split, { ...options, width: 300 });
+                    const split = img.split("src=\"")[1].split("\"")[0];
+                    const doc = Docs.Create.ImageDocument(split, { ...options, width: 300 });
                     ImageUtils.ExtractExif(doc);
                     this.props.addDocument(doc);
                     return;
                 } else {
-                    let path = window.location.origin + "/doc/";
+                    const path = window.location.origin + "/doc/";
                     if (text.startsWith(path)) {
-                        let docid = text.replace(Utils.prepend("/doc/"), "").split("?")[0];
+                        const docid = text.replace(Utils.prepend("/doc/"), "").split("?")[0];
                         DocServer.GetRefField(docid).then(f => {
                             if (f instanceof Doc) {
                                 if (options.x || options.y) { f.x = options.x; f.y = options.y; } // should be in CollectionFreeFormView
@@ -218,7 +218,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                             }
                         });
                     } else {
-                        let htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", width: 300, height: 300, documentText: text });
+                        const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", width: 300, height: 300, documentText: text });
                         this.props.addDocument(htmlDoc);
                     }
                     return;
@@ -231,8 +231,8 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             }
             let matches: RegExpExecArray | null;
             if ((matches = /(https:\/\/)?docs\.google\.com\/document\/d\/([^\\]+)\/edit/g.exec(text)) !== null) {
-                let newBox = Docs.Create.TextDocument({ ...options, width: 400, height: 200, title: "Awaiting title from Google Docs..." });
-                let proto = newBox.proto!;
+                const newBox = Docs.Create.TextDocument({ ...options, width: 400, height: 200, title: "Awaiting title from Google Docs..." });
+                const proto = newBox.proto!;
                 const documentId = matches[2];
                 proto[GoogleRef] = documentId;
                 proto.data = "Please select this document and then click on its pull button to load its contents from from Google Docs...";
@@ -249,17 +249,17 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 const mediaItems = await GooglePhotos.Query.AlbumSearch(albumId);
                 console.log(mediaItems);
             }
-            let batch = UndoManager.StartBatch("collection view drop");
-            let promises: Promise<void>[] = [];
+            const batch = UndoManager.StartBatch("collection view drop");
+            const promises: Promise<void>[] = [];
             // tslint:disable-next-line:prefer-for-of
             for (let i = 0; i < e.dataTransfer.items.length; i++) {
-                let item = e.dataTransfer.items[i];
+                const item = e.dataTransfer.items[i];
                 if (item.kind === "string" && item.type.indexOf("uri") !== -1) {
                     let str: string;
-                    let prom = new Promise<string>(resolve => e.dataTransfer.items[i].getAsString(resolve))
+                    const prom = new Promise<string>(resolve => e.dataTransfer.items[i].getAsString(resolve))
                         .then(action((s: string) => rp.head(Utils.CorsProxy(str = s))))
                         .then(result => {
-                            let type = result["content-type"];
+                            const type = result["content-type"];
                             if (type) {
                                 Docs.Get.DocumentFromType(type, str, { ...options, width: 300, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300 })
                                     .then(doc => doc && this.props.addDocument(doc));
@@ -267,23 +267,23 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                         });
                     promises.push(prom);
                 }
-                let type = item.type;
+                const type = item.type;
                 if (item.kind === "file") {
-                    let file = item.getAsFile();
-                    let formData = new FormData();
+                    const file = item.getAsFile();
+                    const formData = new FormData();
 
                     if (!file || !file.type) {
                         continue;
                     }
 
                     formData.append('file', file);
-                    let dropFileName = file ? file.name : "-empty-";
+                    const dropFileName = file ? file.name : "-empty-";
                     promises.push(Networking.PostFormDataToServer("/upload", formData).then(results => {
                         results.map(action(({ clientAccessPath }: any) => {
-                            let full = { ...options, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300, width: 300, title: dropFileName };
-                            let pathname = Utils.prepend(clientAccessPath);
+                            const full = { ...options, nativeWidth: type.indexOf("video") !== -1 ? 600 : 300, width: 300, title: dropFileName };
+                            const pathname = Utils.prepend(clientAccessPath);
                             Docs.Get.DocumentFromType(type, pathname, full).then(doc => {
-                                doc && (Doc.GetProto(doc).fileUpload = path.basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""));
+                                doc && (Doc.GetProto(doc).fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""));
                                 doc && this.props.addDocument(doc);
                             });
                         }));
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c4b7e2d31..48ea35c6b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -3,7 +3,7 @@ import { faAngleRight, faArrowsAltH, faBell, faCamera, faCaretDown, faCaretRight
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../new_fields/Doc';
+import { Doc, DocListCast, Field, HeightSym, WidthSym } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { Document, listSpec } from '../../../new_fields/Schema';
@@ -95,11 +95,11 @@ class TreeView extends React.Component<TreeViewProps> {
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
     @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
     @computed get fieldKey() {
-        let splits = StrCast(Doc.LayoutField(this.props.document)).split("fieldKey={\"");
+        const splits = StrCast(Doc.LayoutField(this.props.document)).split("fieldKey={\"");
         return splits.length > 1 ? splits[1].split("\"")[0] : "data";
     }
     childDocList(field: string) {
-        let layout = Doc.LayoutField(this.props.document) instanceof Doc ? Doc.LayoutField(this.props.document) as Doc : undefined;
+        const layout = Doc.LayoutField(this.props.document) instanceof Doc ? Doc.LayoutField(this.props.document) as Doc : undefined;
         return ((this.props.dataDoc ? Cast(this.props.dataDoc[field], listSpec(Doc)) : undefined) ||
             (layout ? Cast(layout[field], listSpec(Doc)) : undefined) ||
             Cast(this.props.document[field], listSpec(Doc))) as Doc[];
@@ -149,10 +149,10 @@ class TreeView extends React.Component<TreeViewProps> {
     }
     onDragMove = (e: PointerEvent): void => {
         Doc.UnBrushDoc(this.dataDoc);
-        let pt = [e.clientX, e.clientY]
-        let rect = this._header!.current!.getBoundingClientRect();
-        let before = pt[1] < rect.top + rect.height / 2;
-        let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
+        const pt = [e.clientX, e.clientY];
+        const rect = this._header!.current!.getBoundingClientRect();
+        const before = pt[1] < rect.top + rect.height / 2;
+        const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
         this._header!.current!.className = "treeViewItem-header";
         if (inside) this._header!.current!.className += " treeViewItem-header-inside";
         else if (before) this._header!.current!.className += " treeViewItem-header-above";
@@ -172,8 +172,8 @@ class TreeView extends React.Component<TreeViewProps> {
         SetValue={undoBatch((value: string) => Doc.SetInPlace(this.props.document, key, value, false) || true)}
         OnFillDown={undoBatch((value: string) => {
             Doc.SetInPlace(this.props.document, key, value, false);
-            let layoutDoc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
-            let doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+            const layoutDoc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
+            const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
             TreeView.loadId = doc[Id];
             return this.props.addDocument(doc);
         })}
@@ -205,7 +205,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
                 ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
             }
-            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
+            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
             ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" });
             ContextMenu.Instance.displayMenu(e.pageX > 156 ? e.pageX - 156 : 0, e.pageY - 15);
             e.stopPropagation();
@@ -215,13 +215,13 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @undoBatch
     treeDrop = (e: Event, de: DragManager.DropEvent) => {
-        let pt = [de.x, de.y];
-        let rect = this._header!.current!.getBoundingClientRect();
-        let before = pt[1] < rect.top + rect.height / 2;
-        let inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
+        const pt = [de.x, de.y];
+        const rect = this._header!.current!.getBoundingClientRect();
+        const before = pt[1] < rect.top + rect.height / 2;
+        const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
         if (de.data instanceof DragManager.LinkDragData) {
-            let sourceDoc = de.data.linkSourceDocument;
-            let destDoc = this.props.document;
+            const sourceDoc = de.data.linkSourceDocument;
+            const destDoc = this.props.document;
             DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc });
             e.stopPropagation();
         }
@@ -232,7 +232,7 @@ class TreeView extends React.Component<TreeViewProps> {
             if (inside) {
                 addDoc = (doc: Doc) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) || addDoc(doc);
             }
-            let movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
+            const movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
             return ((de.data.dropAction && (de.data.options !== this.props.treeViewId)) || de.data.userDropAction) ?
                 de.data.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
                 : de.data.moveDocument ?
@@ -243,23 +243,23 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     docTransform = () => {
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
-        let outerXf = this.props.outerXf();
-        let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
-        let finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(this._dref.current!);
+        const outerXf = this.props.outerXf();
+        const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+        const finalXf = this.props.ScreenToLocalTransform().translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
         return finalXf;
     }
     docWidth = () => {
-        let layoutDoc = Doc.Layout(this.props.document);
-        let aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth);
+        const layoutDoc = Doc.Layout(this.props.document);
+        const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth);
         if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 20));
         return NumCast(layoutDoc.nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
     }
     docHeight = () => {
-        let layoutDoc = Doc.Layout(this.props.document);
-        let bounds = this.boundsOfCollectionDocument;
+        const layoutDoc = Doc.Layout(this.props.document);
+        const bounds = this.boundsOfCollectionDocument;
         return Math.min(this.MAX_EMBED_HEIGHT, (() => {
-            let aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth, 1);
+            const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth, 1);
             if (aspect) return this.docWidth() * aspect;
             if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x);
             return layoutDoc.fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection.height) :
@@ -270,18 +270,18 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     @computed get expandedField() {
-        let ids: { [key: string]: string } = {};
-        let doc = this.props.document;
+        const ids: { [key: string]: string } = {};
+        const doc = this.props.document;
         doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
 
-        let rows: JSX.Element[] = [];
-        for (let key of Object.keys(ids).slice().sort()) {
-            let contents = doc[key];
+        const rows: JSX.Element[] = [];
+        for (const key of Object.keys(ids).slice().sort()) {
+            const contents = doc[key];
             let contentElement: (JSX.Element | null)[] | JSX.Element = [];
 
             if (contents instanceof Doc || Cast(contents, listSpec(Doc))) {
-                let remDoc = (doc: Doc) => this.remove(doc, key);
-                let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
+                const remDoc = (doc: Doc) => this.remove(doc, key);
+                const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true);
                 contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
                     DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
@@ -310,9 +310,9 @@ class TreeView extends React.Component<TreeViewProps> {
     @computed get renderContent() {
         const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined;
         if (expandKey !== undefined) {
-            let remDoc = (doc: Doc) => this.remove(doc, expandKey);
-            let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true);
-            let docs = expandKey === "links" ? this.childLinks : this.childDocs;
+            const remDoc = (doc: Doc) => this.remove(doc, expandKey);
+            const addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, expandKey, doc, addBefore, before, false, true);
+            const docs = expandKey === "links" ? this.childLinks : this.childDocs;
             return <ul key={expandKey + "more"}>
                 {!docs ? (null) :
                     TreeView.GetChildElements(docs, this.props.treeViewId, Doc.Layout(this.props.document),
@@ -326,7 +326,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 {this.expandedField}
             </div></ul>;
         } else {
-            let layoutDoc = Doc.Layout(this.props.document);
+            const layoutDoc = Doc.Layout(this.props.document);
             return <div ref={this._dref} style={{ display: "inline-block", height: this.docHeight() }} key={this.props.document[Id] + this.props.document.title}>
                 <ContentFittingDocumentView
                     Document={layoutDoc}
@@ -363,10 +363,10 @@ class TreeView extends React.Component<TreeViewProps> {
      */
     @computed
     get renderTitle() {
-        let reference = React.createRef<HTMLDivElement>();
-        let onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId, true);
+        const reference = React.createRef<HTMLDivElement>();
+        const onItemDown = SetupDrag(reference, () => this.dataDoc, this.move, this.props.dropAction, this.props.treeViewId, true);
 
-        let headerElements = (
+        const headerElements = (
             <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
                 onPointerDown={action(() => {
                     if (this.treeViewOpen) {
@@ -379,7 +379,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 })}>
                 {this.treeViewExpandedView}
             </span>);
-        let openRight = (<div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
+        const openRight = (<div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
             <FontAwesomeIcon title="open in pane on right" icon="angle-right" size="lg" />
         </div>);
         return <>
@@ -440,28 +440,28 @@ class TreeView extends React.Component<TreeViewProps> {
             childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
-        let docs = childDocs.slice();
-        let dataExtension = containingCollection[key + "_ext"] as Doc;
-        let ascending = dataExtension && BoolCast(dataExtension.sortAscending, null);
+        const docs = childDocs.slice();
+        const dataExtension = containingCollection[key + "_ext"] as Doc;
+        const ascending = dataExtension && BoolCast(dataExtension.sortAscending, null);
         if (ascending !== undefined) {
 
-            let sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
-                var reN = /[0-9]*$/;
-                var aA = a.replace(reN, ""); // get rid of trailing numbers
-                var bA = b.replace(reN, "");
+            const sortAlphaNum = (a: string, b: string): 0 | 1 | -1 => {
+                const reN = /[0-9]*$/;
+                const aA = a.replace(reN, ""); // get rid of trailing numbers
+                const bA = b.replace(reN, "");
                 if (aA === bA) {  // if header string matches, then compare numbers numerically
-                    var aN = parseInt(a.match(reN)![0], 10);
-                    var bN = parseInt(b.match(reN)![0], 10);
+                    const aN = parseInt(a.match(reN)![0], 10);
+                    const bN = parseInt(b.match(reN)![0], 10);
                     return aN === bN ? 0 : aN > bN ? 1 : -1;
                 } else {
                     return aA > bA ? 1 : -1;
                 }
-            }
+            };
             docs.sort(function (a, b): 0 | 1 | -1 {
-                let descA = ascending ? b : a;
-                let descB = ascending ? a : b;
-                let first = descA.title;
-                let second = descB.title;
+                const descA = ascending ? b : a;
+                const descB = ascending ? a : b;
+                const first = descA.title;
+                const second = descB.title;
                 // TODO find better way to sort how to sort..................
                 if (typeof first === 'number' && typeof second === 'number') {
                     return (first - second) > 0 ? 1 : -1;
@@ -479,17 +479,17 @@ class TreeView extends React.Component<TreeViewProps> {
             });
         }
 
-        let rowWidth = () => panelWidth() - 20;
+        const rowWidth = () => panelWidth() - 20;
         return docs.map((child, i) => {
             const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, key, child);
             if (!pair.layout || pair.data instanceof Promise) {
                 return (null);
             }
 
-            let indent = i === 0 ? undefined : () => {
+            const indent = i === 0 ? undefined : () => {
                 if (StrCast(docs[i - 1].layout).indexOf("fieldKey") !== -1) {
-                    let fieldKeysub = StrCast(docs[i - 1].layout).split("fieldKey")[1];
-                    let fieldKey = fieldKeysub.split("\"")[1];
+                    const fieldKeysub = StrCast(docs[i - 1].layout).split("fieldKey")[1];
+                    const fieldKey = fieldKeysub.split("\"")[1];
                     if (fieldKey && Cast(docs[i - 1][fieldKey], listSpec(Doc)) !== undefined) {
                         Doc.AddDocToList(docs[i - 1], fieldKey, child);
                         docs[i - 1].treeViewOpen = true;
@@ -497,21 +497,21 @@ class TreeView extends React.Component<TreeViewProps> {
                     }
                 }
             };
-            let outdent = !parentCollectionDoc ? undefined : () => {
+            const outdent = !parentCollectionDoc ? undefined : () => {
                 if (StrCast(parentCollectionDoc.layout).indexOf("fieldKey") !== -1) {
-                    let fieldKeysub = StrCast(parentCollectionDoc.layout).split("fieldKey")[1];
-                    let fieldKey = fieldKeysub.split("\"")[1];
+                    const fieldKeysub = StrCast(parentCollectionDoc.layout).split("fieldKey")[1];
+                    const fieldKey = fieldKeysub.split("\"")[1];
                     Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false);
                     parentCollectionDoc.treeViewOpen = true;
                     remove(child);
                 }
             };
-            let addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
+            const addDocument = (doc: Doc, relativeTo?: Doc, before?: boolean) => {
                 return add(doc, relativeTo ? relativeTo : docs[i], before !== undefined ? before : false);
             };
             const childLayout = Doc.Layout(pair.layout);
-            let rowHeight = () => {
-                let aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
+            const rowHeight = () => {
+                const aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
                 return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
             };
             return !(child instanceof Doc) ? (null) : <TreeView
@@ -566,7 +566,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
 
     @action
     remove = (document: Document): boolean => {
-        let children = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
+        const children = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
         if (children.indexOf(document) !== -1) {
             children.splice(children.indexOf(document), 1);
             return true;
@@ -587,7 +587,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
             e.preventDefault();
             ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
         } else {
-            let layoutItems: ContextMenuProps[] = [];
+            const layoutItems: ContextMenuProps[] = [];
             layoutItems.push({ description: (this.props.Document.preventTreeViewOpen ? "Persist" : "Abandon") + "Treeview State", event: () => this.props.Document.preventTreeViewOpen = !this.props.Document.preventTreeViewOpen, icon: "paint-brush" });
             layoutItems.push({ description: (this.props.Document.hideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.props.Document.hideHeaderFields = !this.props.Document.hideHeaderFields, icon: "paint-brush" });
             ContextMenu.Instance.addItem({ description: "Treeview Options ...", subitems: layoutItems, icon: "eye" });
@@ -606,9 +606,9 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
 
     render() {
-        let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
-        let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
-        let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
+        const dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
+        const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
+        const moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
         return !this.childDocs ? (null) : (
             <div id="body" className="collectionTreeView-dropTarget"
                 style={{ overflow: "auto", background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
@@ -625,8 +625,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                     SetValue={undoBatch((value: string) => Doc.SetInPlace(this.dataDoc, "title", value, false) || true)}
                     OnFillDown={undoBatch((value: string) => {
                         Doc.SetInPlace(this.dataDoc, "title", value, false);
-                        let layoutDoc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
-                        let doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+                        const layoutDoc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
+                        const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
                         TreeView.loadId = doc[Id];
                         Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
                     })} />
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4c49054d2..54f5a2c42 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -84,7 +84,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     public static SetSafeMode(safeMode: boolean) { this._safeMode = safeMode; }
 
     get collectionViewType(): CollectionViewType | undefined {
-        let viewField = Cast(this.props.Document.viewType, "number");
+        const viewField = Cast(this.props.Document.viewType, "number");
         if (CollectionView._safeMode) {
             if (viewField === CollectionViewType.Freeform) {
                 return CollectionViewType.Tree;
@@ -101,7 +101,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
             () => {
                 // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
                 // chrome status may also be view-mode, in reference to stacking view's toggle mode. it is essentially disabled mode, but prevents the toggle button from showing up on the left sidebar.
-                let chromeStatus = this.props.Document.chromeStatus;
+                const chromeStatus = this.props.Document.chromeStatus;
                 if (chromeStatus && (chromeStatus === "disabled" || chromeStatus === "collapsed")) {
                     runInAction(() => this._collapsed = true);
                 }
@@ -119,9 +119,9 @@ export class CollectionView extends Touchable<FieldViewProps> {
 
     @action.bound
     addDocument(doc: Doc): boolean {
-        let targetDataDoc = Doc.GetProto(this.props.Document);
+        const targetDataDoc = Doc.GetProto(this.props.Document);
         Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc);
-        let extension = Doc.fieldExtensionDoc(targetDataDoc, this.props.fieldKey);  // set metadata about the field being rendered (ie, the set of documents) on an extension field for that field
+        const extension = Doc.fieldExtensionDoc(targetDataDoc, this.props.fieldKey);  // set metadata about the field being rendered (ie, the set of documents) on an extension field for that field
         extension && (extension.lastModified = new DateField(new Date(Date.now())));
         Doc.GetProto(doc).lastOpened = new DateField;
         return true;
@@ -129,9 +129,9 @@ export class CollectionView extends Touchable<FieldViewProps> {
 
     @action.bound
     removeDocument(doc: Doc): boolean {
-        let docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView);
+        const docView = DocumentManager.Instance.getDocumentView(doc, this.props.ContainingCollectionView);
         docView && SelectionManager.DeselectDoc(docView);
-        let value = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
+        const value = Cast(this.props.Document[this.props.fieldKey], listSpec(Doc), []);
         let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1);
         index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1);
 
@@ -163,7 +163,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     }
 
     private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
-        let props = { ...this.props, ...renderProps, chromeCollapsed: this._collapsed, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" };
+        const props = { ...this.props, ...renderProps, chromeCollapsed: this._collapsed, ChromeHeight: this.chromeHeight, CollectionView: this, annotationsKey: "" };
         switch (type) {
             case CollectionViewType.Schema: return (<CollectionSchemaView key="collview" {...props} />);
             case CollectionViewType.Docking: return (<CollectionDockingView key="collview" {...props} />);
@@ -186,7 +186,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
 
     private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
-        let chrome = this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking ? (null) :
+        const chrome = this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking ? (null) :
             <CollectionViewBaseChrome CollectionView={this} key="chrome" type={type} collapse={this.collapse} />;
         return [chrome, this.SubViewHelper(type, renderProps)];
     }
@@ -194,8 +194,8 @@ export class CollectionView extends Touchable<FieldViewProps> {
 
     onContextMenu = (e: React.MouseEvent): void => {
         if (!e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
-            let existingVm = ContextMenu.Instance.findByDescription("View Modes...");
-            let subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
+            const existingVm = ContextMenu.Instance.findByDescription("View Modes...");
+            const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
             subItems.push({ description: "Freeform", event: () => { this.props.Document.viewType = CollectionViewType.Freeform; }, icon: "signature" });
             if (CollectionView._safeMode) {
                 ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => this.props.Document.viewType = CollectionViewType.Invalid, icon: "project-diagram" });
@@ -221,13 +221,13 @@ export class CollectionView extends Touchable<FieldViewProps> {
             subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" });
             !existingVm && ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems, icon: "eye" });
 
-            let existing = ContextMenu.Instance.findByDescription("Layout...");
-            let layoutItems = existing && "subitems" in existing ? existing.subitems : [];
+            const existing = ContextMenu.Instance.findByDescription("Layout...");
+            const layoutItems = existing && "subitems" in existing ? existing.subitems : [];
             layoutItems.push({ description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
             !existing && ContextMenu.Instance.addItem({ description: "Layout...", subitems: layoutItems, icon: "hand-point-right" });
 
-            let more = ContextMenu.Instance.findByDescription("More...");
-            let moreItems = more && "subitems" in more ? more.subitems : [];
+            const more = ContextMenu.Instance.findByDescription("More...");
+            const moreItems = more && "subitems" in more ? more.subitems : [];
             moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
             !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
         }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 06fca7c38..4161e5d6e 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -13,7 +13,6 @@ import { DragManager } from "../../util/DragManager";
 import { undoBatch } from "../../util/UndoManager";
 import { EditableView } from "../EditableView";
 import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
-import { DocLike } from "../MetadataEntryMenu";
 import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
@@ -33,7 +32,7 @@ interface Filter {
     contains: boolean;
 }
 
-let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
+const stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
 
 @observer
 export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
@@ -80,11 +79,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
 
     getFilters = (script: string) => {
-        let re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
-        let arr: any[] = re.exec(script);
-        let toReturn: Filter[] = [];
+        const re: any = /(!)?\(\(\(doc\.(\w+)\s+&&\s+\(doc\.\w+\s+as\s+\w+\)\.includes\(\"(\w+)\"\)/g;
+        const arr: any[] = re.exec(script);
+        const toReturn: Filter[] = [];
         if (arr !== null) {
-            let filter: Filter = {
+            const filter: Filter = {
                 key: arr[2],
                 value: arr[3],
                 contains: (arr[1] === "!") ? false : true,
@@ -120,14 +119,14 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
         let fields: Filter[] = [];
         if (this.filterValue) {
-            let string = this.filterValue.script.originalScript;
+            const string = this.filterValue.script.originalScript;
             fields = this.getFilters(string);
         }
 
         runInAction(() => {
             this.addKeyRestrictions(fields);
             // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
-            let chromeStatus = this.props.CollectionView.props.Document.chromeStatus;
+            const chromeStatus = this.props.CollectionView.props.Document.chromeStatus;
             if (chromeStatus) {
                 if (chromeStatus === "disabled") {
                     throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
@@ -183,7 +182,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     @action
     addKeyRestriction = (e: React.MouseEvent) => {
-        let index = this._keyRestrictions.length;
+        const index = this._keyRestrictions.length;
         this._keyRestrictions.push([<KeyRestrictionRow field="" value="" key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[index][1] = value)} />, ""]);
 
         this.openViewSpecs(e);
@@ -194,26 +193,26 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
         this.openViewSpecs(e);
 
-        let keyRestrictionScript = "(" + this._keyRestrictions.map(i => i[1]).filter(i => i.length > 0).join(" && ") + ")";
-        let yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0;
-        let monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0;
-        let weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0;
-        let dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7;
+        const keyRestrictionScript = "(" + this._keyRestrictions.map(i => i[1]).filter(i => i.length > 0).join(" && ") + ")";
+        const yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0;
+        const monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0;
+        const weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0;
+        const dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7;
         let dateRestrictionScript = "";
         if (this._dateValue instanceof Date) {
-            let lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset);
-            let upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1);
+            const lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset);
+            const upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1);
             dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
         }
         else {
-            let createdDate = new Date(this._dateValue);
+            const createdDate = new Date(this._dateValue);
             if (!isNaN(createdDate.getTime())) {
-                let lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset);
-                let upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1);
+                const lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset);
+                const upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1);
                 dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
             }
         }
-        let fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ?
+        const fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ?
             `${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} (${keyRestrictionScript})` :
             `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
             "true";
@@ -270,7 +269,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             value={this.pivotKeyDisplay}
             onChange={action((e: React.ChangeEvent<HTMLInputElement>) => this.pivotKeyDisplay = e.currentTarget.value)}
             onKeyPress={action((e: React.KeyboardEvent<HTMLInputElement>) => {
-                let value = e.currentTarget.value;
+                const value = e.currentTarget.value;
                 if (e.which === 13) {
                     this.pivotKey = value;
                     this.pivotKeyDisplay = "";
@@ -357,7 +356,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     dragPointerMove = (e: PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        let [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y];
+        const [dx, dy] = [e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y];
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
             this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c =>
                 DragManager.StartButtonDrag([this._commandRef.current!], c.script, c.title,
@@ -373,7 +372,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     }
 
     render() {
-        let collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
+        const collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
         return (
             <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined }}>
                 <div className="collectionViewChrome">
@@ -480,7 +479,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 
     getKeySuggestions = async (value: string): Promise<string[]> => {
         value = value.toLowerCase();
-        let docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
+        const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
         if (docs instanceof Doc) {
             return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
         } else {
@@ -571,31 +570,31 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
 
     @undoBatch
     togglePreview = () => {
-        let dividerWidth = 4;
-        let borderWidth = Number(COLLECTION_BORDER_WIDTH);
-        let panelWidth = this.props.CollectionView.props.PanelWidth();
-        let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
-        let tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
+        const dividerWidth = 4;
+        const borderWidth = Number(COLLECTION_BORDER_WIDTH);
+        const panelWidth = this.props.CollectionView.props.PanelWidth();
+        const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
+        const tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
         this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
     }
 
     @undoBatch
     @action
     toggleTextwrap = async () => {
-        let textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
+        const textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
         if (textwrappedRows.length) {
             this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>([]);
         } else {
-            let docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
-            let allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
+            const docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
+            const allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
             this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
         }
     }
 
 
     render() {
-        let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
-        let textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
+        const previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
+        const textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
 
         return (
             <div className="collectionSchemaViewChrome-cont">
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index e35b7d7d3..f3071b316 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -1,8 +1,6 @@
 import * as React from "react";
 import { observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
-import { Doc } from "../../../new_fields/Doc";
 
 interface IKeyRestrictionProps {
     contains: boolean;
@@ -20,13 +18,13 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
     render() {
         if (this._key && this._value) {
             let parsedValue: string | number = `"${this._value}"`;
-            let parsed = parseInt(this._value);
+            const parsed = parseInt(this._value);
             let type = "string";
             if (!isNaN(parsed)) {
                 parsedValue = parsed;
                 type = "number";
             }
-            let scriptText = `${this._contains ? "" : "!"}(((doc.${this._key} && (doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))) ||
+            const scriptText = `${this._contains ? "" : "!"}(((doc.${this._key} && (doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))) ||
                 ((doc.data_ext && doc.data_ext.${this._key}) && (doc.data_ext.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))))`;
             // let doc = new Doc();
             // ((doc.data_ext && doc.data_ext!.text) && (doc.data_ext!.text as string).includes("hello"));
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 4eb9e9d1e..75ee8de32 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -34,7 +34,7 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
     }
 
     async fetchDocuments() {
-        let aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document)).filter(doc => doc !== this.props.Document);
+        const aliases = (await SearchUtil.GetAliasesOfDocument(this.props.Document)).filter(doc => doc !== this.props.Document);
         const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.Document[Id]}"` });
         const map: Map<Doc, Doc> = new Map;
         const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs)));
@@ -129,7 +129,7 @@ export class ButtonSelector extends React.Component<{ Document: Doc, Stack: any
     render() {
         let flyout;
         if (this.hover) {
-            let view = DocumentManager.Instance.getDocumentView(this.props.Document);
+            const view = DocumentManager.Instance.getDocumentView(this.props.Document);
             flyout = !view ? (null) : (
                 <div className="PDS-flyout" title=" " onMouseLeave={this.onMouseLeave}>
                     <DocumentButtonBar views={[view]} stack={this.props.Stack} />
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 4a32c1647..012115b1f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -77,7 +77,7 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
             fontSize: NumCast(pivotDoc.pivotFontSize, 10)
         });
         for (const doc of val) {
-            let layoutDoc = Doc.Layout(doc);
+            const layoutDoc = Doc.Layout(doc);
             let wid = pivotAxisWidth;
             let hgt = layoutDoc.nativeWidth ? (NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth)) * pivotAxisWidth : pivotAxisWidth;
             if (hgt > pivotAxisWidth) {
@@ -100,7 +100,7 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
     });
 
     childPairs.map(pair => {
-        let defaultPosition = {
+        const defaultPosition = {
             x: NumCast(pair.layout.x),
             y: NumCast(pair.layout.y),
             z: NumCast(pair.layout.z),
@@ -108,7 +108,7 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
             height: NumCast(pair.layout.height)
         };
         const pos = docMap.get(pair.layout) || defaultPosition;
-        let data = poolData.get(pair.layout[Id]);
+        const data = poolData.get(pair.layout[Id]);
         if (!data || pos.x !== data.x || pos.y !== data.y || pos.z !== data.z || pos.width !== data.width || pos.height !== data.height) {
             runInAction(() => poolData.set(pair.layout[Id], { transition: "transform 1s", ...pos }));
         }
@@ -118,10 +118,10 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
 
 export function AddCustomFreeFormLayout(doc: Doc, dataKey: string): () => void {
     return () => {
-        let addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
+        const addOverlay = (key: "arrangeScript" | "arrangeInit", options: OverlayElementOptions, params?: Record<string, string>, requiredType?: string) => {
             let overlayDisposer: () => void = emptyFunction; // filled in below after we have a reference to the scriptingBox
             const scriptField = Cast(doc[key], ScriptField);
-            let scriptingBox = <ScriptBox initialText={scriptField && scriptField.script.originalScript}
+            const scriptingBox = <ScriptBox initialText={scriptField && scriptField.script.originalScript}
                 // tslint:disable-next-line: no-unnecessary-callback-wrapper
                 onCancel={() => overlayDisposer()}  // don't get rid of the function wrapper-- we don't want to use the current value of overlayDiposer, but the one set below
                 onSave={(text, onError) => {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index b00728079..5e4b4fd27 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -6,9 +6,8 @@ import "./CollectionFreeFormLinkView.scss";
 import React = require("react");
 import v5 = require("uuid/v5");
 import { DocumentType } from "../../../documents/DocumentTypes";
-import { observable, action, reaction, IReactionDisposer, trace } from "mobx";
-import { StrCast, Cast } from "../../../../new_fields/Types";
-import { TraceMobx } from "../../../../new_fields/util";
+import { observable, action, reaction, IReactionDisposer } from "mobx";
+import { StrCast } from "../../../../new_fields/Types";
 
 export interface CollectionFreeFormLinkViewProps {
     A: DocumentView;
@@ -26,22 +25,22 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
             action(() => {
                 setTimeout(action(() => this._opacity = 1), 0); // since the render code depends on querying the Dom through getBoudndingClientRect, we need to delay triggering render()
                 setTimeout(action(() => this._opacity = 0.05), 750); // this will unhighlight the link line.
-                let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
-                let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
-                let adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!);
-                let bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!);
-                let a = adiv.getBoundingClientRect();
-                let b = bdiv.getBoundingClientRect();
-                let abounds = adiv.parentElement!.getBoundingClientRect();
-                let bbounds = bdiv.parentElement!.getBoundingClientRect();
-                let apt = Utils.closestPtBetweenRectangles(abounds.left, abounds.top, abounds.width, abounds.height,
+                const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+                const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+                const adiv = (acont.length ? acont[0] : this.props.A.ContentDiv!);
+                const bdiv = (bcont.length ? bcont[0] : this.props.B.ContentDiv!);
+                const a = adiv.getBoundingClientRect();
+                const b = bdiv.getBoundingClientRect();
+                const abounds = adiv.parentElement!.getBoundingClientRect();
+                const bbounds = bdiv.parentElement!.getBoundingClientRect();
+                const apt = Utils.closestPtBetweenRectangles(abounds.left, abounds.top, abounds.width, abounds.height,
                     bbounds.left, bbounds.top, bbounds.width, bbounds.height,
                     a.left + a.width / 2, a.top + a.height / 2);
-                let bpt = Utils.closestPtBetweenRectangles(bbounds.left, bbounds.top, bbounds.width, bbounds.height,
+                const bpt = Utils.closestPtBetweenRectangles(bbounds.left, bbounds.top, bbounds.width, bbounds.height,
                     abounds.left, abounds.top, abounds.width, abounds.height,
                     apt.point.x, apt.point.y);
-                let afield = StrCast(this.props.A.props.Document[StrCast(this.props.A.props.layoutKey, "layout")]).indexOf("anchor1") === -1 ? "anchor2" : "anchor1";
-                let bfield = afield === "anchor1" ? "anchor2" : "anchor1";
+                const afield = StrCast(this.props.A.props.Document[StrCast(this.props.A.props.layoutKey, "layout")]).indexOf("anchor1") === -1 ? "anchor2" : "anchor1";
+                const bfield = afield === "anchor1" ? "anchor2" : "anchor1";
                 this.props.A.props.Document[afield + "_x"] = (apt.point.x - abounds.left) / abounds.width * 100;
                 this.props.A.props.Document[afield + "_y"] = (apt.point.y - abounds.top) / abounds.height * 100;
                 this.props.A.props.Document[bfield + "_x"] = (bpt.point.x - bbounds.left) / bbounds.width * 100;
@@ -55,18 +54,18 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
     }
 
     render() {
-        let acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
-        let bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
-        let a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect();
-        let b = (bcont.length ? bcont[0] : this.props.B.ContentDiv!).getBoundingClientRect();
-        let apt = Utils.closestPtBetweenRectangles(a.left, a.top, a.width, a.height,
+        const acont = this.props.A.props.Document.type === DocumentType.LINK ? this.props.A.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+        const bcont = this.props.B.props.Document.type === DocumentType.LINK ? this.props.B.ContentDiv!.getElementsByClassName("docuLinkBox-cont") : [];
+        const a = (acont.length ? acont[0] : this.props.A.ContentDiv!).getBoundingClientRect();
+        const b = (bcont.length ? bcont[0] : this.props.B.ContentDiv!).getBoundingClientRect();
+        const apt = Utils.closestPtBetweenRectangles(a.left, a.top, a.width, a.height,
             b.left, b.top, b.width, b.height,
             a.left + a.width / 2, a.top + a.height / 2);
-        let bpt = Utils.closestPtBetweenRectangles(b.left, b.top, b.width, b.height,
+        const bpt = Utils.closestPtBetweenRectangles(b.left, b.top, b.width, b.height,
             a.left, a.top, a.width, a.height,
             apt.point.x, apt.point.y);
-        let pt1 = [apt.point.x, apt.point.y];
-        let pt2 = [bpt.point.x, bpt.point.y];
+        const pt1 = [apt.point.x, apt.point.y];
+        const pt2 = [bpt.point.x, bpt.point.y];
         return (<line key="linkLine" className="collectionfreeformlinkview-linkLine"
             style={{ opacity: this._opacity }}
             x1={`${pt1[0]}`} y1={`${pt1[1]}`}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index e9191c176..218012fe1 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -72,11 +72,11 @@ export class CollectionFreeFormLinksView extends React.Component {
     }
     @computed
     get uniqueConnections() {
-        let connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
+        const connections = DocumentManager.Instance.LinkedDocumentViews.reduce((drawnPairs, connection) => {
             if (!drawnPairs.reduce((found, drawnPair) => {
-                let match1 = (connection.a === drawnPair.a && connection.b === drawnPair.b);
-                let match2 = (connection.a === drawnPair.b && connection.b === drawnPair.a);
-                let match = match1 || match2;
+                const match1 = (connection.a === drawnPair.a && connection.b === drawnPair.b);
+                const match2 = (connection.a === drawnPair.b && connection.b === drawnPair.a);
+                const match = match1 || match2;
                 if (match && !drawnPair.l.reduce((found, link) => found || link[Id] === connection.l[Id], false)) {
                     drawnPair.l.push(connection.l);
                 }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index b8148852d..bb9ae4326 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -13,14 +13,14 @@ import v5 = require("uuid/v5");
 export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
 
     protected getCursors(): CursorField[] {
-        let doc = this.props.Document;
+        const doc = this.props.Document;
 
-        let id = CurrentUserUtils.id;
+        const id = CurrentUserUtils.id;
         if (!id) {
             return [];
         }
 
-        let cursors = Cast(doc.cursors, listSpec(CursorField));
+        const cursors = Cast(doc.cursors, listSpec(CursorField));
 
         const now = mobxUtils.now();
         // const now = Date.now();
@@ -30,7 +30,7 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
     private crosshairs?: HTMLCanvasElement;
     drawCrosshairs = (backgroundColor: string) => {
         if (this.crosshairs) {
-            let ctx = this.crosshairs.getContext('2d');
+            const ctx = this.crosshairs.getContext('2d');
             if (ctx) {
                 ctx.fillStyle = backgroundColor;
                 ctx.fillRect(0, 0, 20, 20);
@@ -62,8 +62,8 @@ export class CollectionFreeFormRemoteCursors extends React.Component<CollectionV
 
     get sharedCursors() {
         return this.getCursors().map(c => {
-            let m = c.data.metadata;
-            let l = c.data.position;
+            const m = c.data.metadata;
+            const l = c.data.position;
             this.drawCrosshairs("#" + v5(m.id, v5.URL).substring(0, 6).toUpperCase() + "22");
             return (
                 <div key={m.id} className="collectionFreeFormRemoteCursors-cont"
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 9506ce084..c69b264c4 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1,12 +1,12 @@
 import { library } from "@fortawesome/fontawesome-svg-core";
 import { faEye } from "@fortawesome/free-regular-svg-icons";
 import { faBraille, faChalkboard, faCompass, faCompressArrowsAlt, faExpandArrowsAlt, faFileUpload, faPaintBrush, faTable, faUpload } from "@fortawesome/free-solid-svg-icons";
-import { action, computed, observable, trace, ObservableMap, untracked, reaction, runInAction, IReactionDisposer } from "mobx";
+import { action, computed, observable, ObservableMap, reaction, runInAction, IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../../new_fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt, WidthSym, DocListCastAsync } from "../../../../new_fields/Doc";
 import { documentSchema, positionSchema } from "../../../../new_fields/documentSchemas";
 import { Id } from "../../../../new_fields/FieldSymbols";
-import { InkTool } from "../../../../new_fields/InkField";
+import { InkTool, InkField, InkData } from "../../../../new_fields/InkField";
 import { createSchema, makeInterface } from "../../../../new_fields/Schema";
 import { ScriptField } from "../../../../new_fields/ScriptField";
 import { BoolCast, Cast, DateCast, NumCast, StrCast } from "../../../../new_fields/Types";
@@ -26,7 +26,7 @@ import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss"
 import { ContextMenu } from "../../ContextMenu";
 import { ContextMenuProps } from "../../ContextMenuItem";
 import { InkingControl } from "../../InkingControl";
-import { CreatePolyline, InkingStroke } from "../../InkingStroke";
+import { CreatePolyline } from "../../InkingStroke";
 import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
 import { DocumentViewProps } from "../../nodes/DocumentView";
 import { FormattedTextBox } from "../../nodes/FormattedTextBox";
@@ -39,8 +39,9 @@ import "./CollectionFreeFormView.scss";
 import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
 import { MarqueeView } from "./MarqueeView";
 import React = require("react");
-import { computedFn, keepAlive } from "mobx-utils";
+import { computedFn } from "mobx-utils";
 import { TraceMobx } from "../../../../new_fields/util";
+import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
@@ -98,10 +99,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
     private addLiveTextBox = (newBox: Doc) => {
         FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-        let maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+        const maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
         let heading = maxHeading === 0 || this.childDocs.length === 0 ? 1 : maxHeading === 1 ? 2 : 0;
         if (heading === 0) {
-            let sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 :
+            const sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 :
                 DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date < DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? -1 : 0);
             heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading);
         }
@@ -109,7 +110,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         this.addDocument(newBox);
     }
     private addDocument = (newBox: Doc) => {
-        let added = this.props.addDocument(newBox);
+        const added = this.props.addDocument(newBox);
         added && this.bringToFront(newBox);
         added && this.updateCluster(newBox);
         return added;
@@ -126,36 +127,36 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     onDrop = (e: React.DragEvent): Promise<void> => {
-        var pt = this.getTransform().transformPoint(e.pageX, e.pageY);
+        const pt = this.getTransform().transformPoint(e.pageX, e.pageY);
         return super.onDrop(e, { x: pt[0], y: pt[1] });
     }
 
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        let xf = this.getTransform();
-        let xfo = this.getTransformOverlay();
-        let [xp, yp] = xf.transformPoint(de.x, de.y);
-        let [xpo, ypo] = xfo.transformPoint(de.x, de.y);
+        const xf = this.getTransform();
+        const xfo = this.getTransformOverlay();
+        const [xp, yp] = xf.transformPoint(de.x, de.y);
+        const [xpo, ypo] = xfo.transformPoint(de.x, de.y);
         if (super.drop(e, de)) {
             if (de.data instanceof DragManager.DocumentDragData) {
                 if (de.data.droppedDocuments.length) {
-                    let firstDoc = de.data.droppedDocuments[0];
-                    let z = NumCast(firstDoc.z);
-                    let x = (z ? xpo : xp) - de.data.offset[0];
-                    let y = (z ? ypo : yp) - de.data.offset[1];
-                    let dropX = NumCast(firstDoc.x);
-                    let dropY = NumCast(firstDoc.y);
+                    const firstDoc = de.data.droppedDocuments[0];
+                    const z = NumCast(firstDoc.z);
+                    const x = (z ? xpo : xp) - de.data.offset[0];
+                    const y = (z ? ypo : yp) - de.data.offset[1];
+                    const dropX = NumCast(firstDoc.x);
+                    const dropY = NumCast(firstDoc.y);
                     de.data.droppedDocuments.forEach(action((d: Doc) => {
-                        let layoutDoc = Doc.Layout(d);
+                        const layoutDoc = Doc.Layout(d);
                         d.x = x + NumCast(d.x) - dropX;
                         d.y = y + NumCast(d.y) - dropY;
                         if (!NumCast(layoutDoc.width)) {
                             layoutDoc.width = 300;
                         }
                         if (!NumCast(layoutDoc.height)) {
-                            let nw = NumCast(layoutDoc.nativeWidth);
-                            let nh = NumCast(layoutDoc.nativeHeight);
+                            const nw = NumCast(layoutDoc.nativeWidth);
+                            const nh = NumCast(layoutDoc.nativeHeight);
                             layoutDoc.height = nw && nh ? nh / nw * NumCast(layoutDoc.width) : 300;
                         }
                         this.bringToFront(d);
@@ -166,11 +167,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             }
             else if (de.data instanceof DragManager.AnnotationDragData) {
                 if (de.data.dropDocument) {
-                    let dragDoc = de.data.dropDocument;
-                    let x = xp - de.data.offset[0];
-                    let y = yp - de.data.offset[1];
-                    let dropX = NumCast(dragDoc.x);
-                    let dropY = NumCast(dragDoc.y);
+                    const dragDoc = de.data.dropDocument;
+                    const x = xp - de.data.offset[0];
+                    const y = yp - de.data.offset[1];
+                    const dropX = NumCast(dragDoc.x);
+                    const dropY = NumCast(dragDoc.y);
                     dragDoc.x = x + NumCast(dragDoc.x) - dropX;
                     dragDoc.y = y + NumCast(dragDoc.y) - dropY;
                     de.data.targetContext = this.props.Document; // dropped a PDF annotation, so we need to set the targetContext on the dragData which the PDF view uses at the end of the drop operation
@@ -183,23 +184,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     pickCluster(probe: number[]) {
         return this.childLayoutPairs.map(pair => pair.layout).reduce((cluster, cd) => {
-            let layoutDoc = Doc.Layout(cd);
-            let cx = NumCast(cd.x) - this._clusterDistance;
-            let cy = NumCast(cd.y) - this._clusterDistance;
-            let cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
-            let ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
+            const layoutDoc = Doc.Layout(cd);
+            const cx = NumCast(cd.x) - this._clusterDistance;
+            const cy = NumCast(cd.y) - this._clusterDistance;
+            const cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
+            const ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
             return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ?
                 NumCast(cd.cluster) : cluster;
         }, -1);
     }
     tryDragCluster(e: PointerEvent | TouchEvent) {
-        let ptsParent = e instanceof PointerEvent ? e : e.targetTouches.item(0);
+        const ptsParent = e instanceof PointerEvent ? e : e.targetTouches.item(0);
         if (ptsParent) {
-            let cluster = this.pickCluster(this.getTransform().transformPoint(ptsParent.clientX, ptsParent.clientY));
+            const cluster = this.pickCluster(this.getTransform().transformPoint(ptsParent.clientX, ptsParent.clientY));
             if (cluster !== -1) {
-                let eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => NumCast(cd.cluster) === cluster);
-                let clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!);
-                let de = new DragManager.DocumentDragData(eles);
+                const eles = this.childLayoutPairs.map(pair => pair.layout).filter(cd => NumCast(cd.cluster) === cluster);
+                const clusterDocs = eles.map(ele => DocumentManager.Instance.getDocumentView(ele, this.props.CollectionView)!);
+                const de = new DragManager.DocumentDragData(eles);
                 de.moveDocument = this.props.moveDocument;
                 const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0);
                 de.offset = this.getTransform().transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
@@ -225,10 +226,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @undoBatch
     @action
     updateCluster(doc: Doc) {
-        let childLayouts = this.childLayoutPairs.map(pair => pair.layout);
+        const childLayouts = this.childLayoutPairs.map(pair => pair.layout);
         if (this.props.Document.useClusters) {
             this._clusterSets.map(set => Doc.IndexOf(doc, set) !== -1 && set.splice(Doc.IndexOf(doc, set), 1));
-            let preferredInd = NumCast(doc.cluster);
+            const preferredInd = NumCast(doc.cluster);
             doc.cluster = -1;
             this._clusterSets.map((set, i) => set.map(member => {
                 if (doc.cluster === -1 && Doc.IndexOf(member, childLayouts) !== -1 && Doc.overlapping(doc, member, this._clusterDistance)) {
@@ -255,15 +256,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     getClusterColor = (doc: Doc) => {
         let clusterColor = "";
-        let cluster = NumCast(doc.cluster);
+        const cluster = NumCast(doc.cluster);
         if (this.Document.useClusters) {
             if (this._clusterSets.length <= cluster) {
                 setTimeout(() => this.updateCluster(doc), 0);
             } else {
                 // choose a cluster color from a palette
-                let colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"];
+                const colors = ["#da42429e", "#31ea318c", "#8c4000", "#4a7ae2c4", "#d809ff", "#ff7601", "#1dffff", "yellow", "#1b8231f2", "#000000ad"];
                 clusterColor = colors[cluster % colors.length];
-                let set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor));
+                const set = this._clusterSets[cluster] && this._clusterSets[cluster].filter(s => s.backgroundColor && (s.backgroundColor !== s.defaultBackgroundColor));
                 // override the cluster color with an explicitly set color on a non-background document.  then override that with an explicitly set color on a background document
                 set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
                 set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
@@ -287,7 +288,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
                 e.stopPropagation();
                 e.preventDefault();
-                let point = this.getTransform().transformPoint(e.pageX, e.pageY);
+                const point = this.getTransform().transformPoint(e.pageX, e.pageY);
                 this._points.push({ x: point[0], y: point[1] });
             }
             // if not using a pen and in no ink mode
@@ -324,7 +325,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     handle1PointerDown = (e: React.TouchEvent) => {
-        let pt = e.targetTouches.item(0);
+        const pt = e.targetTouches.item(0);
         if (pt) {
             this._hitCluster = this.props.Document.useCluster ? this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)) !== -1 : false;
         }
@@ -335,9 +336,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && this._points.length <= 1) return;
 
         if (this._points.length > 1) {
-            let B = this.svgBounds;
-            let points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top }));
-            let inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top });
+            const B = this.svgBounds;
+            const points = this._points.map(p => ({ x: p.x - B.left, y: p.y - B.top }));
+            const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top });
             this.addDocument(inkDoc);
             this._points = [];
         }
@@ -355,26 +356,26 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
         let x = this.Document.panX || 0;
         let y = this.Document.panY || 0;
-        let docs = this.childLayoutPairs.map(pair => pair.layout);
-        let [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
+        const docs = this.childLayoutPairs.map(pair => pair.layout);
+        const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
         if (!this.isAnnotationOverlay) {
             PDFMenu.Instance.fadeOut(true);
-            let minx = docs.length ? NumCast(docs[0].x) : 0;
-            let maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
-            let miny = docs.length ? NumCast(docs[0].y) : 0;
-            let maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
-            let ranges = docs.filter(doc => doc).reduce((range, doc) => {
-                let layoutDoc = Doc.Layout(doc);
-                let x = NumCast(doc.x);
-                let xe = x + NumCast(layoutDoc.width);
-                let y = NumCast(doc.y);
-                let ye = y + NumCast(layoutDoc.height);
+            const minx = docs.length ? NumCast(docs[0].x) : 0;
+            const maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
+            const miny = docs.length ? NumCast(docs[0].y) : 0;
+            const maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
+            const ranges = docs.filter(doc => doc).reduce((range, doc) => {
+                const layoutDoc = Doc.Layout(doc);
+                const x = NumCast(doc.x);
+                const xe = x + NumCast(layoutDoc.width);
+                const y = NumCast(doc.y);
+                const ye = y + NumCast(layoutDoc.height);
                 return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
                 [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
             }, [[minx, maxx], [miny, maxy]]);
 
-            let cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1;
-            let panelDim = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth() / this.zoomScaling() * cscale,
+            const cscale = this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.scale) : 1;
+            const panelDim = this.props.ScreenToLocalTransform().transformDirection(this.props.PanelWidth() / this.zoomScaling() * cscale,
                 this.props.PanelHeight() / this.zoomScaling() * cscale);
             if (ranges[0][0] - dx > (this.panX() + panelDim[0] / 2)) x = ranges[0][1] + panelDim[0] / 2;
             if (ranges[0][1] - dx < (this.panX() - panelDim[0] / 2)) x = ranges[0][0] - panelDim[0] / 2;
@@ -397,7 +398,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         if (!e.cancelBubble) {
             const selectedTool = InkingControl.Instance.selectedTool;
             if (selectedTool === InkTool.Highlighter || selectedTool === InkTool.Pen || InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
-                let point = this.getTransform().transformPoint(e.clientX, e.clientY);
+                const point = this.getTransform().transformPoint(e.clientX, e.clientY);
                 this._points.push({ x: point[0], y: point[1] });
             }
             else if (selectedTool === InkTool.None) {
@@ -418,7 +419,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     handle1PointerMove = (e: TouchEvent) => {
         // panning a workspace
         if (!e.cancelBubble) {
-            let pt = e.targetTouches.item(0);
+            const pt = e.targetTouches.item(0);
             if (pt) {
                 if (InkingControl.Instance.selectedTool === InkTool.None) {
                     if (this._hitCluster && this.tryDragCluster(e)) {
@@ -431,7 +432,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     this.pan(pt);
                 }
                 else if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) {
-                    let point = this.getTransform().transformPoint(pt.clientX, pt.clientY);
+                    const point = this.getTransform().transformPoint(pt.clientX, pt.clientY);
                     this._points.push({ x: point[0], y: point[1] });
                 }
             }
@@ -443,28 +444,28 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     handle2PointersMove = (e: TouchEvent) => {
         // pinch zooming
         if (!e.cancelBubble) {
-            let pt1: Touch | null = e.targetTouches.item(0);
-            let pt2: Touch | null = e.targetTouches.item(1);
+            const pt1: Touch | null = e.targetTouches.item(0);
+            const pt2: Touch | null = e.targetTouches.item(1);
             if (!pt1 || !pt2) return;
 
             if (this.prevPoints.size === 2) {
-                let oldPoint1 = this.prevPoints.get(pt1.identifier);
-                let oldPoint2 = this.prevPoints.get(pt2.identifier);
+                const oldPoint1 = this.prevPoints.get(pt1.identifier);
+                const oldPoint2 = this.prevPoints.get(pt2.identifier);
                 if (oldPoint1 && oldPoint2) {
-                    let dir = InteractionUtils.Pinching(pt1, pt2, oldPoint1, oldPoint2);
+                    const dir = InteractionUtils.Pinching(pt1, pt2, oldPoint1, oldPoint2);
 
                     // if zooming, zoom
                     if (dir !== 0) {
-                        let d1 = Math.sqrt(Math.pow(pt1.clientX - oldPoint1.clientX, 2) + Math.pow(pt1.clientY - oldPoint1.clientY, 2));
-                        let d2 = Math.sqrt(Math.pow(pt2.clientX - oldPoint2.clientX, 2) + Math.pow(pt2.clientY - oldPoint2.clientY, 2));
-                        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-                        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+                        const d1 = Math.sqrt(Math.pow(pt1.clientX - oldPoint1.clientX, 2) + Math.pow(pt1.clientY - oldPoint1.clientY, 2));
+                        const d2 = Math.sqrt(Math.pow(pt2.clientX - oldPoint2.clientX, 2) + Math.pow(pt2.clientY - oldPoint2.clientY, 2));
+                        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+                        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
 
                         // calculate the raw delta value
-                        let rawDelta = (dir * (d1 + d2));
+                        const rawDelta = (dir * (d1 + d2));
 
                         // this floors and ceils the delta value to prevent jitteriness
-                        let delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 16);
+                        const delta = Math.sign(rawDelta) * Math.min(Math.abs(rawDelta), 16);
                         this.zoom(centerX, centerY, delta);
                         this.prevPoints.set(pt1.identifier, pt1);
                         this.prevPoints.set(pt2.identifier, pt2);
@@ -472,8 +473,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     // this is not zooming. derive some form of panning from it.
                     else {
                         // use the centerx and centery as the "new mouse position"
-                        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-                        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+                        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+                        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
                         this.pan({ clientX: centerX, clientY: centerY });
                         this._lastX = centerX;
                         this._lastY = centerY;
@@ -486,12 +487,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     handle2PointersDown = (e: React.TouchEvent) => {
-        let pt1: React.Touch | null = e.targetTouches.item(0);
-        let pt2: React.Touch | null = e.targetTouches.item(1);
+        const pt1: React.Touch | null = e.targetTouches.item(0);
+        const pt2: React.Touch | null = e.targetTouches.item(1);
         if (!pt1 || !pt2) return;
 
-        let centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
-        let centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
+        const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
+        const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
         this._lastX = centerX;
         this._lastY = centerY;
     }
@@ -510,11 +511,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             deltaScale = 1 / this.zoomScaling();
         }
         if (deltaScale < 0) deltaScale = -deltaScale;
-        let [x, y] = this.getTransform().transformPoint(pointX, pointY);
-        let localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
+        const [x, y] = this.getTransform().transformPoint(pointX, pointY);
+        const localTransform = this.getLocalTransform().inverse().scaleAbout(deltaScale, x, y);
 
         if (localTransform.Scale >= 0.15) {
-            let safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
+            const safeScale = Math.min(Math.max(0.15, localTransform.Scale), 40);
             this.props.Document.scale = Math.abs(safeScale);
             this.setPan(-localTransform.TranslateX / safeScale, -localTransform.TranslateY / safeScale);
         }
@@ -536,7 +537,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     setPan(panX: number, panY: number, panType: string = "None") {
         if (!this.Document.lockedTransform || this.Document.inOverlay) {
             this.Document.panTransformType = panType;
-            var scale = this.getLocalTransform().inverse().Scale;
+            const scale = this.getLocalTransform().inverse().Scale;
             const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
             const newPanY = Math.min((this.props.Document.scrollHeight !== undefined ? NumCast(this.Document.scrollHeight) : (1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
             this.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
@@ -576,23 +577,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
         SelectionManager.DeselectAll();
         if (this.props.Document.scrollHeight) {
-            let annotOn = Cast(doc.annotationOn, Doc) as Doc;
+            const annotOn = Cast(doc.annotationOn, Doc) as Doc;
             if (!annotOn) {
                 this.props.focus(doc);
             } else {
-                let contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
-                let offset = annotOn && (contextHgt / 2 * 96 / 72);
+                const contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
+                const offset = annotOn && (contextHgt / 2 * 96 / 72);
                 this.props.Document.scrollY = NumCast(doc.y) - offset;
             }
         } else {
-            let layoutdoc = Doc.Layout(doc);
+            const layoutdoc = Doc.Layout(doc);
             const newPanX = NumCast(doc.x) + NumCast(layoutdoc.width) / 2;
             const newPanY = NumCast(doc.y) + NumCast(layoutdoc.height) / 2;
             const newState = HistoryUtil.getState();
             newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
             HistoryUtil.pushState(newState);
 
-            let savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
+            const savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
 
             this.setPan(newPanX, newPanY, "Ease");
             Doc.BrushDoc(this.props.Document);
@@ -677,7 +678,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
     }
 
-    childDataProvider = computedFn(function childDataProvider(doc: Doc) { return (this as any)._layoutPoolData.get(doc[Id]); }.bind(this));
+    childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc) { return this._layoutPoolData.get(doc[Id]); }.bind(this));
 
     doPivotLayout(poolData: ObservableMap<string, any>) {
         return computePivotLayout(poolData, this.props.Document, this.childDocs,
@@ -685,10 +686,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     doFreeformLayout(poolData: ObservableMap<string, any>) {
-        let layoutDocs = this.childLayoutPairs.map(pair => pair.layout);
+        const layoutDocs = this.childLayoutPairs.map(pair => pair.layout);
         const initResult = this.Document.arrangeInit && this.Document.arrangeInit.script.run({ docs: layoutDocs, collection: this.Document }, console.log);
         let state = initResult && initResult.success ? initResult.result.scriptState : undefined;
-        let elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
+        const elements = initResult && initResult.success ? this.viewDefsToJSX(initResult.result.views) : [];
 
         this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map((pair, i) => {
             const data = poolData.get(pair.layout[Id]);
@@ -737,7 +738,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     layoutDocsInGrid = () => {
         UndoManager.RunInBatch(() => {
             const docs = DocListCast(this.Document[this.props.fieldKey]);
-            let startX = this.Document.panX || 0;
+            const startX = this.Document.panX || 0;
             let x = startX;
             let y = this.Document.panY || 0;
             let i = 0;
@@ -762,8 +763,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         this.Document.isRuleProvider && this.childLayoutPairs.map(pair =>
             // iterate over the children of a displayed document (or if the displayed document is a template, iterate over the children of that template)
             DocListCast(Doc.Layout(pair.layout).data).map(heading => {
-                let headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
-                let headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
+                const headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
+                const headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
                 if (headingLayout && NumCast(headingLayout.heading) > 0 && headingLayout.backgroundColor !== headingLayout.defaultBackgroundColor) {
                     Doc.GetProto(this.props.Document)["ruleColor_" + NumCast(headingLayout.heading)] = headingLayout.backgroundColor;
                 }
@@ -772,11 +773,23 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     analyzeStrokes = async () => {
-        //  CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], data.inkData);
+        const children = await DocListCastAsync(this.dataDoc.data);
+        if (!children) {
+            return;
+        }
+        const inkData: InkData[] = [];
+        for (const doc of children) {
+            const data = Cast(doc.data, InkField)?.inkData;
+            data && inkData.push(data);
+        }
+        if (!inkData.length) {
+            return;
+        }
+        CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.dataDoc, ["inkAnalysis", "handwriting"], inkData);
     }
 
     onContextMenu = (e: React.MouseEvent) => {
-        let layoutItems: ContextMenuProps[] = [];
+        const layoutItems: ContextMenuProps[] = [];
 
         if (this.childDocs.some(d => BoolCast(d.isTemplateDoc))) {
             layoutItems.push({ description: "Template Layout Instance", event: () => this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight"), icon: "project-diagram" });
@@ -795,7 +808,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 input.accept = ".zip";
                 input.onchange = async _e => {
                     const upload = Utils.prepend("/uploadDoc");
-                    let formData = new FormData();
+                    const formData = new FormData();
                     const file = input.files && input.files[0];
                     if (file) {
                         formData.append('file', file);
@@ -830,7 +843,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
 
     private childViews = () => {
-        let children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
+        const children = typeof this.props.children === "function" ? (this.props.children as any)() as JSX.Element[] : [];
         return [
             ...children,
             ...this.views,
@@ -838,12 +851,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     @computed get svgBounds() {
-        let xs = this._points.map(p => p.x);
-        let ys = this._points.map(p => p.y);
-        let right = Math.max(...xs);
-        let left = Math.min(...xs);
-        let bottom = Math.max(...ys);
-        let top = Math.min(...ys);
+        const xs = this._points.map(p => p.x);
+        const ys = this._points.map(p => p.y);
+        const right = Math.max(...xs);
+        const left = Math.min(...xs);
+        const bottom = Math.max(...ys);
+        const top = Math.min(...ys);
         return { right: right, left: left, bottom: bottom, top: top, width: right - left, height: bottom - top };
     }
 
@@ -852,7 +865,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             return (null);
         }
 
-        let B = this.svgBounds;
+        const B = this.svgBounds;
 
         return (
             <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)` }}>
@@ -862,7 +875,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     children = () => {
-        let eles: JSX.Element[] = [];
+        const eles: JSX.Element[] = [];
         this.extensionDoc && (eles.push(...this.childViews()));
         this.currentStroke && (eles.push(this.currentStroke));
         eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
@@ -917,7 +930,7 @@ interface CollectionFreeFormViewPannableContentsProps {
 @observer
 class CollectionFreeFormViewPannableContents extends React.Component<CollectionFreeFormViewPannableContentsProps>{
     render() {
-        let freeformclass = "collectionfreeformview" + (this.props.easing() ? "-ease" : "-none");
+        const freeformclass = "collectionfreeformview" + (this.props.easing() ? "-ease" : "-none");
         const cenx = this.props.centeringShiftX();
         const ceny = this.props.centeringShiftY();
         const panx = -this.props.panX();
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index 28ddc19d7..32e39d25e 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -21,7 +21,7 @@ export default class MarqueeOptionsMenu extends AntimodeMenu {
     }
 
     render() {
-        let buttons = [
+        const buttons = [
             <button
                 className="antimodeMenu-button"
                 title="Create a Collection"
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 5ed3fecb5..dc68ae81c 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -1,7 +1,7 @@
 import { action, computed, observable } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast } from "../../../../new_fields/Doc";
-import { InkField, PointData } from "../../../../new_fields/InkField";
+import { InkField } from "../../../../new_fields/InkField";
 import { List } from "../../../../new_fields/List";
 import { listSpec } from "../../../../new_fields/Schema";
 import { SchemaHeaderField } from "../../../../new_fields/SchemaHeaderField";
@@ -15,11 +15,9 @@ import { Transform } from "../../../util/Transform";
 import { undoBatch } from "../../../util/UndoManager";
 import { PreviewCursor } from "../../PreviewCursor";
 import { CollectionViewType } from "../CollectionView";
-import { CollectionFreeFormView } from "./CollectionFreeFormView";
 import "./MarqueeView.scss";
 import React = require("react");
 import MarqueeOptionsMenu from "./MarqueeOptionsMenu";
-import InkSelectDecorations from "../../InkSelectDecorations";
 import { SubCollectionViewProps } from "../CollectionSubView";
 
 interface MarqueeViewProps {
@@ -67,26 +65,27 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     @action
     onKeyPress = (e: KeyboardEvent) => {
         //make textbox and add it to this collection
+        // tslint:disable-next-line:prefer-const
         let [x, y] = this.props.getTransform().transformPoint(this._downX, this._downY);
         if (e.key === "q" && e.ctrlKey) {
             e.preventDefault();
             (async () => {
-                let text: string = await navigator.clipboard.readText();
-                let ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
+                const text: string = await navigator.clipboard.readText();
+                const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
                 for (let i = 0; i < ns.length - 1; i++) {
                     while (!(ns[i].trim() === "" || ns[i].endsWith("-\r") || ns[i].endsWith("-") ||
                         ns[i].endsWith(";\r") || ns[i].endsWith(";") ||
                         ns[i].endsWith(".\r") || ns[i].endsWith(".") ||
                         ns[i].endsWith(":\r") || ns[i].endsWith(":")) && i < ns.length - 1) {
-                        let sub = ns[i].endsWith("\r") ? 1 : 0;
-                        let br = ns[i + 1].trim() === "";
+                        const sub = ns[i].endsWith("\r") ? 1 : 0;
+                        const br = ns[i + 1].trim() === "";
                         ns.splice(i, 2, ns[i].substr(0, ns[i].length - sub) + ns[i + 1].trimLeft());
                         if (br) break;
                     }
                 }
                 ns.map(line => {
-                    let indent = line.search(/\S|$/);
-                    let newBox = Docs.Create.TextDocument({ width: 200, height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line });
+                    const indent = line.search(/\S|$/);
+                    const newBox = Docs.Create.TextDocument({ width: 200, height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line });
                     this.props.addDocument(newBox);
                     y += 40 * this.props.getTransform().Scale;
                 });
@@ -94,7 +93,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         } else if (e.key === "b" && e.ctrlKey) {
             e.preventDefault();
             navigator.clipboard.readText().then(text => {
-                let ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
+                const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
                 if (ns.length === 1 && text.startsWith("http")) {
                     this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
                 } else {
@@ -105,8 +104,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             this.props.addLiveTextDocument(
                 Docs.Create.TextDocument({ width: 200, height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" }));
         } else if (e.keyCode > 48 && e.keyCode <= 57) {
-            let notes = DocListCast((CurrentUserUtils.UserDocument.noteTypes as Doc).data);
-            let text = Docs.Create.TextDocument({ width: 200, height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" });
+            const notes = DocListCast((CurrentUserUtils.UserDocument.noteTypes as Doc).data);
+            const text = Docs.Create.TextDocument({ width: 200, height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" });
             text.layout = notes[(e.keyCode - 49) % notes.length];
             this.props.addLiveTextDocument(text);
         }
@@ -124,31 +123,31 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             ns.splice(0, 1);
         }
         if (ns.length > 0) {
-            let columns = ns[0].split("\t");
-            let docList: Doc[] = [];
+            const columns = ns[0].split("\t");
+            const docList: Doc[] = [];
             let groupAttr: string | number = "";
-            let rowProto = new Doc();
+            const rowProto = new Doc();
             rowProto.title = rowProto.Id;
             rowProto.width = 200;
             rowProto.isPrototype = true;
             for (let i = 1; i < ns.length - 1; i++) {
-                let values = ns[i].split("\t");
+                const values = ns[i].split("\t");
                 if (values.length === 1 && columns.length > 1) {
                     groupAttr = values[0];
                     continue;
                 }
-                let docDataProto = Doc.MakeDelegate(rowProto);
+                const docDataProto = Doc.MakeDelegate(rowProto);
                 docDataProto.isPrototype = true;
                 columns.forEach((col, i) => docDataProto[columns[i]] = (values.length > i ? ((values[i].indexOf(Number(values[i]).toString()) !== -1) ? Number(values[i]) : values[i]) : undefined));
                 if (groupAttr) {
                     docDataProto._group = groupAttr;
                 }
                 docDataProto.title = i.toString();
-                let doc = Doc.MakeDelegate(docDataProto);
+                const doc = Doc.MakeDelegate(docDataProto);
                 doc.width = 200;
                 docList.push(doc);
             }
-            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
+            const newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
 
             this.props.addDocument(newCol);
         }
@@ -193,13 +192,13 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     onPointerUp = (e: PointerEvent): void => {
         if (!this.props.active(true)) this.props.selectDocuments([this.props.Document], []);
         if (this._visible) {
-            let mselect = this.marqueeSelect();
+            const mselect = this.marqueeSelect();
             if (!e.shiftKey) {
                 SelectionManager.DeselectAll(mselect.length ? undefined : this.props.Document);
             }
             // let inkselect = this.ink ? this.marqueeInkSelect(this.ink.inkData) : new Map();
             // let inks = inkselect.size ? [{ Document: this.inkDoc, Ink: inkselect }] : [];
-            let docs = mselect.length ? mselect : [this.props.Document];
+            const docs = mselect.length ? mselect : [this.props.Document];
             this.props.selectDocuments(docs, []);
         }
         if (!this._commandExecuted && (Math.abs(this.Bounds.height * this.Bounds.width) > 100)) {
@@ -212,7 +211,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         }
         this.cleanupInteractions(true, this._commandExecuted);
 
-        let hideMarquee = () => {
+        const hideMarquee = () => {
             this.hideMarquee();
             MarqueeOptionsMenu.Instance.fadeOut(true);
             document.removeEventListener("pointerdown", hideMarquee);
@@ -260,10 +259,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
 
     @computed
     get Bounds() {
-        let left = this._downX < this._lastX ? this._downX : this._lastX;
-        let top = this._downY < this._lastY ? this._downY : this._lastY;
-        let topLeft = this.props.getTransform().transformPoint(left, top);
-        let size = this.props.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
+        const left = this._downX < this._lastX ? this._downX : this._lastX;
+        const top = this._downY < this._lastY ? this._downY : this._lastY;
+        const topLeft = this.props.getTransform().transformPoint(left, top);
+        const size = this.props.getTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
         return { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
     }
 
@@ -302,15 +301,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     }
 
     getCollection = (selected: Doc[]) => {
-        let bounds = this.Bounds;
-        let defaultPalette = ["rgb(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
+        const bounds = this.Bounds;
+        const defaultPalette = ["rgb(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
             "rgb(209,150,226)", "rgb(127,235,144)", "rgb(252,188,189)", "rgb(247,175,81)",];
-        let colorPalette = Cast(this.props.Document.colorPalette, listSpec("string"));
+        const colorPalette = Cast(this.props.Document.colorPalette, listSpec("string"));
         if (!colorPalette) this.props.Document.colorPalette = new List<string>(defaultPalette);
-        let palette = Array.from(Cast(this.props.Document.colorPalette, listSpec("string")) as string[]);
-        let usedPaletted = new Map<string, number>();
+        const palette = Array.from(Cast(this.props.Document.colorPalette, listSpec("string")) as string[]);
+        const usedPaletted = new Map<string, number>();
         [...this.props.activeDocuments(), this.props.Document].map(child => {
-            let bg = StrCast(Doc.Layout(child).backgroundColor);
+            const bg = StrCast(Doc.Layout(child).backgroundColor);
             if (palette.indexOf(bg) !== -1) {
                 palette.splice(palette.indexOf(bg), 1);
                 if (usedPaletted.get(bg)) usedPaletted.set(bg, usedPaletted.get(bg)! + 1);
@@ -320,10 +319,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         usedPaletted.delete("#f1efeb");
         usedPaletted.delete("white");
         usedPaletted.delete("rgba(255,255,255,1)");
-        let usedSequnce = Array.from(usedPaletted.keys()).sort((a, b) => usedPaletted.get(a)! < usedPaletted.get(b)! ? -1 : usedPaletted.get(a)! > usedPaletted.get(b)! ? 1 : 0);
-        let chosenColor = (usedPaletted.size === 0) ? "white" : palette.length ? palette[0] : usedSequnce[0];
-        let inkData = this.ink ? this.ink.inkData : undefined;
-        let newCollection = Docs.Create.FreeformDocument(selected, {
+        const usedSequnce = Array.from(usedPaletted.keys()).sort((a, b) => usedPaletted.get(a)! < usedPaletted.get(b)! ? -1 : usedPaletted.get(a)! > usedPaletted.get(b)! ? 1 : 0);
+        const chosenColor = (usedPaletted.size === 0) ? "white" : palette.length ? palette[0] : usedSequnce[0];
+        // const inkData = this.ink ? this.ink.inkData : undefined;
+        const newCollection = Docs.Create.FreeformDocument(selected, {
             x: bounds.left,
             y: bounds.top,
             panX: 0,
@@ -334,7 +333,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             height: bounds.height,
             title: "a nested collection",
         });
-        let dataExtensionField = Doc.CreateDocumentExtensionForField(newCollection, "data");
+        // const dataExtensionField = Doc.CreateDocumentExtensionForField(newCollection, "data");
         // dataExtensionField.ink = inkData ? new InkField(this.marqueeInkSelect(inkData)) : undefined;
         // this.marqueeInkDelete(inkData);
         this.hideMarquee();
@@ -343,8 +342,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
 
     @action
     collection = (e: KeyboardEvent | React.PointerEvent | undefined) => {
-        let bounds = this.Bounds;
-        let selected = this.marqueeSelect(false);
+        const bounds = this.Bounds;
+        const selected = this.marqueeSelect(false);
         if (e instanceof KeyboardEvent ? e.key === "c" : true) {
             selected.map(d => {
                 this.props.removeDocument(d);
@@ -354,7 +353,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 return d;
             });
         }
-        let newCollection = this.getCollection(selected);
+        const newCollection = this.getCollection(selected);
         this.props.addDocument(newCollection);
         this.props.selectDocuments([newCollection], []);
         MarqueeOptionsMenu.Instance.fadeOut(true);
@@ -363,9 +362,9 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
 
     @action
     summary = (e: KeyboardEvent | React.PointerEvent | undefined) => {
-        let bounds = this.Bounds;
-        let selected = this.marqueeSelect(false);
-        let newCollection = this.getCollection(selected);
+        const bounds = this.Bounds;
+        const selected = this.marqueeSelect(false);
+        const newCollection = this.getCollection(selected);
 
         selected.map(d => {
             this.props.removeDocument(d);
@@ -375,13 +374,13 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             return d;
         });
         newCollection.chromeStatus = "disabled";
-        let summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, autoHeight: true, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
+        const summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, autoHeight: true, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
         Doc.GetProto(summary).summarizedDocs = new List<Doc>([newCollection]);
         newCollection.x = bounds.left + bounds.width;
         Doc.GetProto(newCollection).summaryDoc = summary;
         Doc.GetProto(newCollection).title = ComputedField.MakeFunction(`summaryTitle(this);`);
         if (e instanceof KeyboardEvent ? e.key === "s" : true) { // summary is wrapped in an expand/collapse container that also contains the summarized documents in a free form view.
-            let container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" });
+            const container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" });
             container.viewType = CollectionViewType.Stacking;
             container.autoHeight = true;
             Doc.GetProto(summary).maximizeLocation = "inPlace";  // or "onRight"
@@ -462,42 +461,42 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     // }
 
     marqueeSelect(selectBackgrounds: boolean = true) {
-        let selRect = this.Bounds;
-        let selection: Doc[] = [];
+        const selRect = this.Bounds;
+        const selection: Doc[] = [];
         this.props.activeDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => {
-            let layoutDoc = Doc.Layout(doc);
-            var x = NumCast(doc.x);
-            var y = NumCast(doc.y);
-            var w = NumCast(layoutDoc.width);
-            var h = NumCast(layoutDoc.height);
+            const layoutDoc = Doc.Layout(doc);
+            const x = NumCast(doc.x);
+            const y = NumCast(doc.y);
+            const w = NumCast(layoutDoc.width);
+            const h = NumCast(layoutDoc.height);
             if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
                 selection.push(doc);
             }
         });
         if (!selection.length && selectBackgrounds) {
             this.props.activeDocuments().filter(doc => doc.z === undefined).map(doc => {
-                let layoutDoc = Doc.Layout(doc);
-                var x = NumCast(doc.x);
-                var y = NumCast(doc.y);
-                var w = NumCast(layoutDoc.width);
-                var h = NumCast(layoutDoc.height);
+                const layoutDoc = Doc.Layout(doc);
+                const x = NumCast(doc.x);
+                const y = NumCast(doc.y);
+                const w = NumCast(layoutDoc.width);
+                const h = NumCast(layoutDoc.height);
                 if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
                     selection.push(doc);
                 }
             });
         }
         if (!selection.length) {
-            let left = this._downX < this._lastX ? this._downX : this._lastX;
-            let top = this._downY < this._lastY ? this._downY : this._lastY;
-            let topLeft = this.props.getContainerTransform().transformPoint(left, top);
-            let size = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
-            let otherBounds = { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
+            const left = this._downX < this._lastX ? this._downX : this._lastX;
+            const top = this._downY < this._lastY ? this._downY : this._lastY;
+            const topLeft = this.props.getContainerTransform().transformPoint(left, top);
+            const size = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
+            const otherBounds = { left: topLeft[0], top: topLeft[1], width: Math.abs(size[0]), height: Math.abs(size[1]) };
             this.props.activeDocuments().filter(doc => doc.z !== undefined).map(doc => {
-                let layoutDoc = Doc.Layout(doc);
-                var x = NumCast(doc.x);
-                var y = NumCast(doc.y);
-                var w = NumCast(layoutDoc.width);
-                var h = NumCast(layoutDoc.height);
+                const layoutDoc = Doc.Layout(doc);
+                const x = NumCast(doc.x);
+                const y = NumCast(doc.y);
+                const w = NumCast(layoutDoc.width);
+                const h = NumCast(layoutDoc.height);
                 if (this.intersectRect({ left: x, top: y, width: w, height: h }, otherBounds)) {
                     selection.push(doc);
                 }
@@ -508,8 +507,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
 
     @computed
     get marqueeDiv() {
-        let p: [number, number] = this._visible ? this.props.getContainerTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY) : [0, 0];
-        let v = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
+        const p: [number, number] = this._visible ? this.props.getContainerTransform().transformPoint(this._downX < this._lastX ? this._downX : this._lastX, this._downY < this._lastY ? this._downY : this._lastY) : [0, 0];
+        const v = this.props.getContainerTransform().transformDirection(this._lastX - this._downX, this._lastY - this._downY);
         /**
          * @RE - The commented out span below
          * This contains the "C for collection, ..." text on marquees.
diff --git a/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx b/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
index f8104cef3..3aaf4120c 100644
--- a/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
+++ b/src/client/views/document_templates/caption_toggle/DetailedCaptionToggle.tsx
@@ -1,8 +1,8 @@
 import * as React from 'react';
-import { FontWeightProperty, FontStyleProperty, FontSizeProperty, ColorProperty } from 'csstype';
+import { FontStyleProperty, ColorProperty } from 'csstype';
 import { observer } from 'mobx-react';
 import { observable, action, runInAction } from 'mobx';
-import { FormattedTextBox, FormattedTextBoxProps } from '../../nodes/FormattedTextBox';
+import { FormattedTextBox } from '../../nodes/FormattedTextBox';
 import { FieldViewProps } from '../../nodes/FieldView';
 
 interface DetailedCaptionDataProps {
@@ -33,7 +33,7 @@ export default class DetailedCaptionToggle extends React.Component<DetailedCapti
     }
 
     render() {
-        let size = this.props.toggleSize || 20;
+        const size = this.props.toggleSize || 20;
         return (
             <div style={{
                 transition: "0.5s opacity ease",
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index ecb3e9db4..bb8a8b47b 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -43,12 +43,12 @@ class GroupTypesDropdown extends React.Component<GroupTypesDropdownProps> {
     @action
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
-            let allGroupTypes = Array.from(LinkManager.Instance.getAllGroupTypes());
-            let groupOptions = allGroupTypes.filter(groupType => groupType.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-            let exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase());
+            const allGroupTypes = Array.from(LinkManager.Instance.getAllGroupTypes());
+            const groupOptions = allGroupTypes.filter(groupType => groupType.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+            const exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase());
 
             if (exactFound > -1) {
-                let groupType = groupOptions[exactFound];
+                const groupType = groupOptions[exactFound];
                 this.props.setGroupType(groupType);
                 this._groupType = groupType;
             } else {
@@ -84,19 +84,19 @@ class GroupTypesDropdown extends React.Component<GroupTypesDropdownProps> {
     renderOptions = (): JSX.Element[] | JSX.Element => {
         if (this._searchTerm === "") return <></>;
 
-        let allGroupTypes = Array.from(LinkManager.Instance.getAllGroupTypes());
-        let groupOptions = allGroupTypes.filter(groupType => groupType.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
-        let exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
+        const allGroupTypes = Array.from(LinkManager.Instance.getAllGroupTypes());
+        const groupOptions = allGroupTypes.filter(groupType => groupType.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
+        const exactFound = groupOptions.findIndex(groupType => groupType.toUpperCase() === this._searchTerm.toUpperCase()) > -1;
 
-        let options = groupOptions.map(groupType => {
-            let ref = React.createRef<HTMLDivElement>();
+        const options = groupOptions.map(groupType => {
+            const ref = React.createRef<HTMLDivElement>();
             return <div key={groupType} ref={ref} className="linkEditor-option"
                 onClick={() => this.onOptionClick(groupType, false)}>{groupType}</div>;
         });
 
         // if search term does not already exist as a group type, give option to create new group type
         if (!exactFound && this._searchTerm !== "") {
-            let ref = React.createRef<HTMLDivElement>();
+            const ref = React.createRef<HTMLDivElement>();
             options.push(<div key={""} ref={ref} className="linkEditor-option"
                 onClick={() => this.onOptionClick(this._searchTerm, true)}>Define new "{this._searchTerm}" relationship</div>);
         }
@@ -138,10 +138,10 @@ class LinkMetadataEditor extends React.Component<LinkMetadataEditorProps> {
 
     @action
     setMetadataKey = (value: string): void => {
-        let groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);
+        const groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);
 
         // don't allow user to create existing key
-        let newIndex = groupMdKeys.findIndex(key => key.toUpperCase() === value.toUpperCase());
+        const newIndex = groupMdKeys.findIndex(key => key.toUpperCase() === value.toUpperCase());
         if (newIndex > -1) {
             this._keyError = true;
             this._key = value;
@@ -151,7 +151,7 @@ class LinkMetadataEditor extends React.Component<LinkMetadataEditorProps> {
         }
 
         // set new value for key
-        let currIndex = groupMdKeys.findIndex(key => {
+        const currIndex = groupMdKeys.findIndex(key => {
             return StrCast(key).toUpperCase() === this._key.toUpperCase();
         });
         if (currIndex === -1) console.error("LinkMetadataEditor: key was not found");
@@ -172,9 +172,9 @@ class LinkMetadataEditor extends React.Component<LinkMetadataEditorProps> {
 
     @action
     removeMetadata = (): void => {
-        let groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);
+        const groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);
 
-        let index = groupMdKeys.findIndex(key => key.toUpperCase() === this._key.toUpperCase());
+        const index = groupMdKeys.findIndex(key => key.toUpperCase() === this._key.toUpperCase());
         if (index === -1) console.error("LinkMetadataEditor: key was not found");
         groupMdKeys.splice(index, 1);
 
@@ -206,7 +206,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     constructor(props: LinkGroupEditorProps) {
         super(props);
 
-        let groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(StrCast(props.groupDoc.type));
+        const groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(StrCast(props.groupDoc.type));
         groupMdKeys.forEach(key => {
             this._metadataIds.set(key, Utils.GenerateGuid());
         });
@@ -226,25 +226,25 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     }
 
     copyGroup = async (groupType: string): Promise<void> => {
-        let sourceGroupDoc = this.props.groupDoc;
+        const sourceGroupDoc = this.props.groupDoc;
         const sourceMdDoc = await Cast(sourceGroupDoc.metadata, Doc);
         if (!sourceMdDoc) return;
 
-        let destDoc = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
+        const destDoc = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
         // let destGroupList = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, destDoc);
-        let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
+        const keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
 
         // create new metadata doc with copied kvp
-        let destMdDoc = new Doc();
+        const destMdDoc = new Doc();
         destMdDoc.anchor1 = StrCast(sourceMdDoc.anchor2);
         destMdDoc.anchor2 = StrCast(sourceMdDoc.anchor1);
         keys.forEach(key => {
-            let val = sourceMdDoc[key] === undefined ? "" : StrCast(sourceMdDoc[key]);
+            const val = sourceMdDoc[key] === undefined ? "" : StrCast(sourceMdDoc[key]);
             destMdDoc[key] = val;
         });
 
         // create new group doc with new metadata doc
-        let destGroupDoc = new Doc();
+        const destGroupDoc = new Doc();
         destGroupDoc.type = groupType;
         destGroupDoc.metadata = destMdDoc;
 
@@ -256,7 +256,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     @action
     addMetadata = (groupType: string): void => {
         this._metadataIds.set("new key", Utils.GenerateGuid());
-        let mdKeys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
+        const mdKeys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
         // only add "new key" if there is no other key with value "new key"; prevents spamming
         if (mdKeys.indexOf("new key") === -1) mdKeys.push("new key");
         LinkManager.Instance.setMetadataKeysForGroup(groupType, mdKeys);
@@ -268,17 +268,17 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     }
 
     renderMetadata = (): JSX.Element[] => {
-        let metadata: Array<JSX.Element> = [];
-        let groupDoc = this.props.groupDoc;
+        const metadata: Array<JSX.Element> = [];
+        const groupDoc = this.props.groupDoc;
         const mdDoc = FieldValue(Cast(groupDoc.metadata, Doc));
         if (!mdDoc) {
             return [];
         }
-        let groupType = StrCast(groupDoc.type);
-        let groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
+        const groupType = StrCast(groupDoc.type);
+        const groupMdKeys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
 
         groupMdKeys.forEach((key) => {
-            let val = StrCast(mdDoc[key]);
+            const val = StrCast(mdDoc[key]);
             metadata.push(
                 <LinkMetadataEditor key={"mded-" + this._metadataIds.get(key)} id={this._metadataIds.get(key)!} groupType={groupType} mdDoc={mdDoc} mdKey={key} mdValue={val} changeMdIdKey={this.changeMdIdKey} />
             );
@@ -287,18 +287,18 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
     }
 
     viewGroupAsTable = (groupType: string): JSX.Element => {
-        let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
-        let index = keys.indexOf("");
+        const keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
+        const index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
-        let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
-        let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
-        let ref = React.createRef<HTMLDivElement>();
+        const cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
+        const docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
+        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
+        const ref = React.createRef<HTMLDivElement>();
         return <div ref={ref}><button className="linkEditor-button" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>;
     }
 
     render() {
-        let groupType = StrCast(this.props.groupDoc.type);
+        const groupType = StrCast(this.props.groupDoc.type);
         // if ((groupType && LinkManager.Instance.getMetadataKeysInGroup(groupType).length > 0) || groupType === "") {
         let buttons;
         if (groupType === "") {
@@ -356,15 +356,15 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
     @action
     addGroup = (): void => {
         // create new metadata document for group
-        let mdDoc = new Doc();
+        const mdDoc = new Doc();
         mdDoc.anchor1 = this.props.sourceDoc.title;
-        let opp = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
+        const opp = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
         if (opp) {
             mdDoc.anchor2 = opp.title;
         }
 
         // create new group document
-        let groupDoc = new Doc();
+        const groupDoc = new Doc();
         groupDoc.type = "";
         groupDoc.metadata = mdDoc;
 
@@ -372,10 +372,10 @@ export class LinkEditor extends React.Component<LinkEditorProps> {
     }
 
     render() {
-        let destination = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
+        const destination = LinkManager.Instance.getOppositeAnchor(this.props.linkDoc, this.props.sourceDoc);
 
-        let groupList = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, this.props.sourceDoc);
-        let groups = groupList.map(groupDoc => {
+        const groupList = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, this.props.sourceDoc);
+        const groups = groupList.map(groupDoc => {
             return <LinkGroupEditor key={"gred-" + StrCast(groupDoc.type)} linkDoc={this.props.linkDoc} sourceDoc={this.props.sourceDoc} groupDoc={groupDoc} />;
         });
 
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index efe2c7f2a..29e167ff7 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -68,14 +68,14 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
         this._contextDisposer = reaction(
             () => this.selectedContextString,
             async () => {
-                let ref = await DocServer.GetRefField(this.selectedContextString);
+                const ref = await DocServer.GetRefField(this.selectedContextString);
                 runInAction(() => {
                     if (ref instanceof Doc) {
                         this.selectedContext = ref;
                     }
                 });
                 if (this.selectedContext instanceof Doc) {
-                    let aliases = await SearchUtil.GetViewsOfDocument(this.selectedContext);
+                    const aliases = await SearchUtil.GetViewsOfDocument(this.selectedContext);
                     runInAction(() => { this.selectedContextAliases = aliases; });
                 }
             }
@@ -90,8 +90,8 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
         if (LinkFollowBox.destinationDoc && this.sourceView && this.sourceView.props.ContainingCollectionDoc) {
             runInAction(() => this.canPan = false);
             if (this.sourceView.props.ContainingCollectionDoc.viewType === CollectionViewType.Freeform) {
-                let docs = Cast(this.sourceView.props.ContainingCollectionDoc.data, listSpec(Doc), []);
-                let aliases = await SearchUtil.GetViewsOfDocument(Doc.GetProto(LinkFollowBox.destinationDoc));
+                const docs = Cast(this.sourceView.props.ContainingCollectionDoc.data, listSpec(Doc), []);
+                const aliases = await SearchUtil.GetViewsOfDocument(Doc.GetProto(LinkFollowBox.destinationDoc));
 
                 aliases.forEach(alias => {
                     if (docs.filter(doc => doc === alias).length > 0) {
@@ -118,8 +118,8 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
 
     async fetchDocuments() {
         if (LinkFollowBox.destinationDoc) {
-            let dest: Doc = LinkFollowBox.destinationDoc;
-            let aliases = await SearchUtil.GetViewsOfDocument(Doc.GetProto(dest));
+            const dest: Doc = LinkFollowBox.destinationDoc;
+            const aliases = await SearchUtil.GetViewsOfDocument(Doc.GetProto(dest));
             const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${dest[Id]}"` });
             const map: Map<Doc, Doc> = new Map;
             const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs)));
@@ -128,7 +128,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
             runInAction(async () => {
                 this._docs = docs.filter(doc => !Doc.AreProtosEqual(doc, CollectionDockingView.Instance.props.Document)).map(doc => ({ col: doc, target: dest }));
                 this._otherDocs = Array.from(map.entries()).filter(entry => !Doc.AreProtosEqual(entry[0], CollectionDockingView.Instance.props.Document)).map(([col, target]) => ({ col, target }));
-                let tcontext = LinkFollowBox.linkDoc && (await Cast(LinkFollowBox.linkDoc.anchor2Context, Doc)) as Doc;
+                const tcontext = LinkFollowBox.linkDoc && (await Cast(LinkFollowBox.linkDoc.anchor2Context, Doc)) as Doc;
                 runInAction(() => tcontext && this._docs.splice(0, 0, { col: tcontext, target: dest }));
             });
         }
@@ -157,7 +157,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     openFullScreen = () => {
         if (LinkFollowBox.destinationDoc) {
-            let view = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
+            const view = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
             view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
         }
     }
@@ -171,7 +171,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
                 options.context.panX = newPanX;
                 options.context.panY = newPanY;
             }
-            let view = DocumentManager.Instance.getDocumentView(options.context);
+            const view = DocumentManager.Instance.getDocumentView(options.context);
             view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
             this.highlightDoc();
         }
@@ -211,7 +211,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     openLinkRight = () => {
         if (LinkFollowBox.destinationDoc) {
-            let alias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
+            const alias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
             (LinkFollowBox._addDocTab || this.props.addDocTab)(alias, undefined, "onRight");
             this.highlightDoc();
             SelectionManager.DeselectAll();
@@ -222,7 +222,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     jumpToLink = async (options: { shouldZoom: boolean }) => {
         if (LinkFollowBox.sourceDoc && LinkFollowBox.linkDoc) {
-            let focus = (document: Doc) => { (LinkFollowBox._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
+            const focus = (document: Doc) => { (LinkFollowBox._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
             //let focus = (doc: Doc, maxLocation: string) => this.props.focus(docthis.props.focus(LinkFollowBox.destinationDoc, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation));
 
             DocumentManager.Instance.FollowLink(LinkFollowBox.linkDoc, LinkFollowBox.sourceDoc, focus, options && options.shouldZoom, false, undefined);
@@ -232,7 +232,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     openLinkTab = () => {
         if (LinkFollowBox.destinationDoc) {
-            let fullScreenAlias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
+            const fullScreenAlias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
             // this.prosp.addDocTab is empty -- use the link source's addDocTab 
             (LinkFollowBox._addDocTab || this.props.addDocTab)(fullScreenAlias, undefined, "inTab");
 
@@ -264,14 +264,14 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
 
         if (LinkFollowBox.destinationDoc && LinkFollowBox.sourceDoc) {
             if (this.sourceView && this.sourceView.props.addDocument) {
-                let destViews = DocumentManager.Instance.getDocumentViews(LinkFollowBox.destinationDoc);
+                const destViews = DocumentManager.Instance.getDocumentViews(LinkFollowBox.destinationDoc);
                 if (!destViews.find(dv => dv.props.ContainingCollectionView === this.sourceView!.props.ContainingCollectionView)) {
-                    let alias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
-                    let y = NumCast(LinkFollowBox.sourceDoc.y);
-                    let x = NumCast(LinkFollowBox.sourceDoc.x);
+                    const alias = Doc.MakeAlias(LinkFollowBox.destinationDoc);
+                    const y = NumCast(LinkFollowBox.sourceDoc.y);
+                    const x = NumCast(LinkFollowBox.sourceDoc.x);
 
-                    let width = NumCast(LinkFollowBox.sourceDoc.width);
-                    let height = NumCast(LinkFollowBox.sourceDoc.height);
+                    const width = NumCast(LinkFollowBox.sourceDoc.width);
+                    const height = NumCast(LinkFollowBox.sourceDoc.height);
 
                     alias.x = x + width + 30;
                     alias.y = y;
@@ -301,8 +301,8 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
                 this.selectedContext = LinkFollowBox.destinationDoc;
             }
             if (this.selectedOption === "") this.selectedOption = FollowOptions.NOZOOM;
-            let shouldZoom: boolean = this.selectedOption === FollowOptions.NOZOOM ? false : true;
-            let notOpenInContext: boolean = this.selectedContextString === "self" || this.selectedContextString === LinkFollowBox.destinationDoc[Id];
+            const shouldZoom: boolean = this.selectedOption === FollowOptions.NOZOOM ? false : true;
+            const notOpenInContext: boolean = this.selectedContextString === "self" || this.selectedContextString === LinkFollowBox.destinationDoc[Id];
 
             if (this.selectedMode === FollowModes.INPLACE) {
                 if (shouldZoom !== undefined) this.openLinkInPlace({ shouldZoom: shouldZoom });
@@ -328,7 +328,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
 
     @action
     handleModeChange = (e: React.ChangeEvent) => {
-        let target = e.target as HTMLInputElement;
+        const target = e.target as HTMLInputElement;
         this.selectedMode = target.value;
         this.selectedContext = undefined;
         this.selectedContextString = "";
@@ -345,13 +345,13 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
 
     @action
     handleOptionChange = (e: React.ChangeEvent) => {
-        let target = e.target as HTMLInputElement;
+        const target = e.target as HTMLInputElement;
         this.selectedOption = target.value;
     }
 
     @action
     handleContextChange = (e: React.ChangeEvent) => {
-        let target = e.target as HTMLInputElement;
+        const target = e.target as HTMLInputElement;
         this.selectedContextString = target.value;
         // selectedContext is updated in reaction
         this.selectedOption = "";
@@ -360,7 +360,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @computed
     get canOpenInPlace() {
         if (this.sourceView && this.sourceView.props.ContainingCollectionDoc) {
-            let colDoc = this.sourceView.props.ContainingCollectionDoc;
+            const colDoc = this.sourceView.props.ContainingCollectionDoc;
             if (colDoc.viewType && colDoc.viewType === CollectionViewType.Freeform) return true;
         }
         return false;
diff --git a/src/client/views/linking/LinkMenu.tsx b/src/client/views/linking/LinkMenu.tsx
index 27af873b5..52628ba4c 100644
--- a/src/client/views/linking/LinkMenu.tsx
+++ b/src/client/views/linking/LinkMenu.tsx
@@ -34,7 +34,7 @@ export class LinkMenu extends React.Component<Props> {
     }
 
     renderAllGroups = (groups: Map<string, Array<Doc>>): Array<JSX.Element> => {
-        let linkItems: Array<JSX.Element> = [];
+        const linkItems: Array<JSX.Element> = [];
         groups.forEach((group, groupType) => {
             linkItems.push(
                 <LinkMenuGroup
@@ -55,8 +55,8 @@ export class LinkMenu extends React.Component<Props> {
     }
 
     render() {
-        let sourceDoc = this.props.docView.props.Document;
-        let groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
+        const sourceDoc = this.props.docView.props.Document;
+        const groups: Map<string, Doc[]> = LinkManager.Instance.getRelatedGroupedLinks(sourceDoc);
         if (this._editingLink === undefined) {
             return (
                 <div className="linkMenu">
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 1891919ce..15aacbbc9 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -51,11 +51,11 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
                 document.removeEventListener("pointermove", this.onLinkButtonMoved);
                 document.removeEventListener("pointerup", this.onLinkButtonUp);
 
-                let draggedDocs = this.props.group.map(linkDoc => {
-                    let opp = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc);
+                const draggedDocs = this.props.group.map(linkDoc => {
+                    const opp = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc);
                     if (opp) return opp;
                 }) as Doc[];
-                let dragData = new DragManager.DocumentDragData(draggedDocs);
+                const dragData = new DragManager.DocumentDragData(draggedDocs);
 
                 DragManager.StartLinkedDocumentDrag([this._drag.current], dragData, e.x, e.y, {
                     handlers: {
@@ -69,19 +69,19 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
     }
 
     viewGroupAsTable = (groupType: string): JSX.Element => {
-        let keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
-        let index = keys.indexOf("");
+        const keys = LinkManager.Instance.getMetadataKeysInGroup(groupType);
+        const index = keys.indexOf("");
         if (index > -1) keys.splice(index, 1);
-        let cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
-        let docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
-        let createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
-        let ref = React.createRef<HTMLDivElement>();
+        const cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
+        const docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
+        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
+        const ref = React.createRef<HTMLDivElement>();
         return <div ref={ref}><button className="linkEditor-button linkEditor-tableButton" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>;
     }
 
     render() {
-        let groupItems = this.props.group.map(linkDoc => {
-            let destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc);
+        const groupItems = this.props.group.map(linkDoc => {
+            const destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc);
             if (destination && this.props.sourceDoc) {
                 return <LinkMenuItem key={destination[Id] + this.props.sourceDoc[Id]}
                     groupType={this.props.groupType}
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 238660de3..edf5e9c26 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -36,15 +36,15 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     }
 
     renderMetadata = (): JSX.Element => {
-        let groups = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, this.props.sourceDoc);
-        let index = groups.findIndex(groupDoc => StrCast(groupDoc.type).toUpperCase() === this.props.groupType.toUpperCase());
-        let groupDoc = index > -1 ? groups[index] : undefined;
+        const groups = LinkManager.Instance.getAnchorGroups(this.props.linkDoc, this.props.sourceDoc);
+        const index = groups.findIndex(groupDoc => StrCast(groupDoc.type).toUpperCase() === this.props.groupType.toUpperCase());
+        const groupDoc = index > -1 ? groups[index] : undefined;
 
         let mdRows: Array<JSX.Element> = [];
         if (groupDoc) {
-            let mdDoc = Cast(groupDoc.metadata, Doc, null);
+            const mdDoc = Cast(groupDoc.metadata, Doc, null);
             if (mdDoc) {
-                let keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
+                const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
                 mdRows = keys.map(key => {
                     return (<div key={key} className="link-metadata-row"><b>{key}</b>: {StrCast(mdDoc[key])}</div>);
                 });
@@ -110,8 +110,8 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
 
     render() {
 
-        let keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
-        let canExpand = keys ? keys.length > 0 : false;
+        const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
+        const canExpand = keys ? keys.length > 0 : false;
 
         return (
             <div className="linkMenu-item">
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 77b10e395..95c765e8a 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -56,19 +56,19 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
         this._linkPlayDisposer = reaction(() => this.layoutDoc.scrollToLinkID,
             scrollLinkId => {
                 scrollLinkId && DocListCast(this.dataDoc.links).filter(l => l[Id] === scrollLinkId).map(l => {
-                    let la1 = l.anchor1 as Doc;
-                    let linkTime = Doc.AreProtosEqual(la1, this.dataDoc) ? NumCast(l.anchor1Timecode) : NumCast(l.anchor2Timecode);
+                    const la1 = l.anchor1 as Doc;
+                    const linkTime = Doc.AreProtosEqual(la1, this.dataDoc) ? NumCast(l.anchor1Timecode) : NumCast(l.anchor2Timecode);
                     setTimeout(() => { this.playFrom(linkTime); Doc.linkFollowHighlight(l); }, 250);
                 });
                 scrollLinkId && Doc.SetInPlace(this.layoutDoc, "scrollToLinkID", undefined, false);
             }, { fireImmediately: true });
         this._reactionDisposer = reaction(() => SelectionManager.SelectedDocuments(),
             selected => {
-                let sel = selected.length ? selected[0].props.Document : undefined;
+                const sel = selected.length ? selected[0].props.Document : undefined;
                 this.Document.playOnSelect && sel && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(DateCast(sel.creationTime).date.getTime());
             });
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, timeInMillisecondsFrom1970 => {
-            let start = this.extensionDoc && DateCast(this.extensionDoc.recordingStart);
+            const start = this.extensionDoc && DateCast(this.extensionDoc.recordingStart);
             start && this.playFrom((timeInMillisecondsFrom1970 - start.date.getTime()) / 1000);
         });
     }
@@ -127,7 +127,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
 
     recordAudioAnnotation = () => {
         let gumStream: any;
-        let self = this;
+        const self = this;
         const extensionDoc = this.extensionDoc;
         extensionDoc && navigator.mediaDevices.getUserMedia({
             audio: true
@@ -160,7 +160,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
     }
 
     specificContextMenu = (e: React.MouseEvent): void => {
-        let funcs: ContextMenuProps[] = [];
+        const funcs: ContextMenuProps[] = [];
         funcs.push({ description: (this.Document.playOnSelect ? "Don't play" : "Play") + " when document selected", event: () => this.Document.playOnSelect = !this.Document.playOnSelect, icon: "expand-arrows-alt" });
 
         ContextMenu.Instance.addItem({ description: "Audio Funcs...", subitems: funcs, icon: "asterisk" });
@@ -170,7 +170,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
         this._recorder.stop();
         this.dataDoc.duration = (new Date().getTime() - this._recordStart) / 1000;
         this._audioState = "recorded";
-        let ind = AudioBox.ActiveRecordings.indexOf(this.props.Document);
+        const ind = AudioBox.ActiveRecordings.indexOf(this.props.Document);
         ind !== -1 && (AudioBox.ActiveRecordings.splice(ind, 1));
     });
 
@@ -198,13 +198,13 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
     }
 
     @computed get path() {
-        let field = Cast(this.props.Document[this.props.fieldKey], AudioField);
-        let path = (field instanceof AudioField) ? field.url.href : "";
+        const field = Cast(this.props.Document[this.props.fieldKey], AudioField);
+        const path = (field instanceof AudioField) ? field.url.href : "";
         return path === nullAudio ? "" : path;
     }
 
     @computed get audio() {
-        let interactive = this.active() ? "-interactive" : "";
+        const interactive = this.active() ? "-interactive" : "";
         return <audio ref={this.setRef} className={`audiobox-control${interactive}`}>
             <source src={this.path} type="audio/mpeg" />
             Not supported.
@@ -212,7 +212,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
     }
 
     render() {
-        let interactive = this.active() ? "-interactive" : "";
+        const interactive = this.active() ? "-interactive" : "";
         return (!this.extensionDoc ? (null) :
             <div className={`audiobox-container`} onContextMenu={this.specificContextMenu}
                 onClick={!this.path ? this.recordClick : undefined}>
@@ -228,7 +228,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
                             <div className="audiobox-timeline" onClick={e => e.stopPropagation()}
                                 onPointerDown={e => {
                                     if (e.button === 0 && !e.ctrlKey) {
-                                        let rect = (e.target as any).getBoundingClientRect();
+                                        const rect = (e.target as any).getBoundingClientRect();
                                         this._ele!.currentTime = this.Document.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
                                         this.pause();
                                         e.stopPropagation();
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index 659ba154a..34151a311 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -51,10 +51,10 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
     }
 
     specificContextMenu = (e: React.MouseEvent): void => {
-        let funcs: ContextMenuProps[] = [];
+        const funcs: ContextMenuProps[] = [];
         funcs.push({
             description: "Clear Script Params", event: () => {
-                let params = FieldValue(this.Document.buttonParams);
+                const params = FieldValue(this.Document.buttonParams);
                 params && params.map(p => this.props.Document[p] = undefined);
             }, icon: "trash"
         });
@@ -73,8 +73,8 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
     }
     // (!missingParams || !missingParams.length ? "" : "(" + missingParams.map(m => m + ":").join(" ") + ")")
     render() {
-        let params = this.Document.buttonParams;
-        let missingParams = params && params.filter(p => this.props.Document[p] === undefined);
+        const params = this.Document.buttonParams;
+        const missingParams = params && params.filter(p => this.props.Document[p] === undefined);
         params && params.map(p => DocListCast(this.props.Document[p])); // bcz: really hacky form of prefetching ... 
         return (
             <div className="buttonBox-outerDiv" ref={this.createDropTarget} onContextMenu={this.specificContextMenu}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 2b079fe50..d599de56e 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -31,7 +31,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
     get Y() { return this._animPos !== undefined ? this._animPos[1] : this.renderScriptDim ? this.renderScriptDim.y : this.props.y !== undefined ? this.props.y : this.dataProvider ? this.dataProvider.y : (this.Document.y || 0); }
     get width() { return this.renderScriptDim ? this.renderScriptDim.width : this.props.width !== undefined ? this.props.width : this.props.dataProvider && this.dataProvider ? this.dataProvider.width : this.layoutDoc[WidthSym](); }
     get height() {
-        let hgt = this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.dataProvider && this.dataProvider ? this.dataProvider.height : this.layoutDoc[HeightSym]();
+        const hgt = this.renderScriptDim ? this.renderScriptDim.height : this.props.height !== undefined ? this.props.height : this.props.dataProvider && this.dataProvider ? this.dataProvider.height : this.layoutDoc[HeightSym]();
         return (hgt === undefined && this.nativeWidth && this.nativeHeight) ? this.width * this.nativeHeight / this.nativeWidth : hgt;
     }
     @computed get dataProvider() { return this.props.dataProvider && this.props.dataProvider(this.props.Document) ? this.props.dataProvider(this.props.Document) : undefined; }
@@ -40,13 +40,13 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     @computed get renderScriptDim() {
         if (this.Document.renderScript) {
-            let someView = Cast(this.props.Document.someView, Doc);
-            let minimap = Cast(this.props.Document.minimap, Doc);
+            const someView = Cast(this.props.Document.someView, Doc);
+            const minimap = Cast(this.props.Document.minimap, Doc);
             if (someView instanceof Doc && minimap instanceof Doc) {
-                let x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2;
-                let y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2;
-                let w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width);
-                let h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height);
+                const x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2;
+                const y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2;
+                const w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width);
+                const h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height);
                 return { x: x, y: y, width: w, height: h };
             }
         }
@@ -70,9 +70,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         .scale(1 / this.contentScaling())
 
     borderRounding = () => {
-        let ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
-        let ld = this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] instanceof Doc ? this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] as Doc : undefined;
-        let br = StrCast((ld || this.props.Document).borderRounding);
+        const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
+        const ld = this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] instanceof Doc ? this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] as Doc : undefined;
+        const br = StrCast((ld || this.props.Document).borderRounding);
         return !br && ruleRounding ? ruleRounding : br;
     }
 
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index a5f96d2de..efc907f9b 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -47,7 +47,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
     private get nativeWidth() { return NumCast(this.layoutDoc!.nativeWidth, this.props.PanelWidth()); }
     private get nativeHeight() { return NumCast(this.layoutDoc!.nativeHeight, this.props.PanelHeight()); }
     private contentScaling = () => {
-        let wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth());
+        const wscale = this.props.PanelWidth() / (this.nativeWidth ? this.nativeWidth : this.props.PanelWidth());
         if (wscale * this.nativeHeight > this.props.PanelHeight()) {
             return this.props.PanelHeight() / (this.nativeHeight ? this.nativeHeight : this.props.PanelHeight());
         }
@@ -59,7 +59,7 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
     drop = (e: Event, de: DragManager.DropEvent) => {
         if (de.data instanceof DragManager.DocumentDragData) {
             this.props.childDocs && this.props.childDocs.map(otherdoc => {
-                let target = Doc.GetProto(otherdoc);
+                const target = Doc.GetProto(otherdoc);
                 target.layout = ComputedField.MakeFunction("this.image_data[0]");
                 target.layoutCustom = Doc.MakeDelegate(de.data.draggedDocuments[0]);
             });
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index d73407903..a22472e9e 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -36,12 +36,12 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
         (e.button === 0 && !e.ctrlKey) && e.stopPropagation();
     }
     onPointerMove = action((e: PointerEvent) => {
-        let cdiv = this._ref && this._ref.current && this._ref.current.parentElement;
+        const cdiv = this._ref && this._ref.current && this._ref.current.parentElement;
         if (cdiv && (Math.abs(e.clientX - this._downx) > 5 || Math.abs(e.clientY - this._downy) > 5)) {
-            let bounds = cdiv.getBoundingClientRect();
-            let pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY);
-            let separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
-            let dragdist = Math.sqrt((pt[0] - this._downx) * (pt[0] - this._downx) + (pt[1] - this._downy) * (pt[1] - this._downy));
+            const bounds = cdiv.getBoundingClientRect();
+            const pt = Utils.getNearestPointInPerimeter(bounds.left, bounds.top, bounds.width, bounds.height, e.clientX, e.clientY);
+            const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
+            const dragdist = Math.sqrt((pt[0] - this._downx) * (pt[0] - this._downx) + (pt[1] - this._downy) * (pt[1] - this._downy));
             if (separation > 100) {
                 DragLinksAsDocuments(this._ref.current!, pt[0], pt[1], Cast(this.props.Document[this.props.fieldKey], Doc) as Doc, this.props.Document); // Containging collection is the document, not a collection... hack.
                 document.removeEventListener("pointermove", this.onPointerMove);
@@ -67,14 +67,14 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
     }
 
     render() {
-        let anchorDoc = Cast(this.props.Document[this.props.fieldKey], Doc);
-        let hasAnchor = anchorDoc instanceof Doc && anchorDoc.type === DocumentType.PDFANNO;
-        let y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100);
-        let x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100);
-        let c = StrCast(this.props.Document.backgroundColor, "lightblue");
-        let anchor = this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1";
-        let timecode = this.props.Document[anchor + "Timecode"];
-        let targetTitle = StrCast((this.props.Document[anchor]! as Doc).title) + (timecode !== undefined ? ":" + timecode : "");
+        const anchorDoc = Cast(this.props.Document[this.props.fieldKey], Doc);
+        const hasAnchor = anchorDoc instanceof Doc && anchorDoc.type === DocumentType.PDFANNO;
+        const y = NumCast(this.props.Document[this.props.fieldKey + "_y"], 100);
+        const x = NumCast(this.props.Document[this.props.fieldKey + "_x"], 100);
+        const c = StrCast(this.props.Document.backgroundColor, "lightblue");
+        const anchor = this.props.fieldKey === "anchor1" ? "anchor2" : "anchor1";
+        const timecode = this.props.Document[anchor + "Timecode"];
+        const targetTitle = StrCast((this.props.Document[anchor]! as Doc).title) + (timecode !== undefined ? ":" + timecode : "");
         return <div className="docuLinkBox-cont" onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle}
             ref={this._ref} style={{
                 background: c, left: `calc(${x}% - 12.5px)`, top: `calc(${y}% - 12.5px)`,
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index b9b84d5ce..13fd3cde1 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -83,7 +83,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     }
 
     CreateBindings(): JsxBindings {
-        let list = {
+        const list = {
             ...OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit,
             Document: this.layoutDoc,
             DataDoc: this.dataDoc,
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 057b4eecd..63ce6233c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -122,7 +122,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     startDragging(x: number, y: number, dropAction: dropActionType, applyAsTemplate?: boolean) {
         if (this._mainCont.current) {
-            let dragData = new DragManager.DocumentDragData([this.props.Document]);
+            const dragData = new DragManager.DocumentDragData([this.props.Document]);
             const [left, top] = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(0, 0);
             dragData.offset = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).transformDirection(x - left, y - top);
             dragData.dropAction = dropAction;
@@ -143,7 +143,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             let preventDefault = true;
             if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
-                let fullScreenAlias = Doc.MakeAlias(this.props.Document);
+                const fullScreenAlias = Doc.MakeAlias(this.props.Document);
                 if (StrCast(fullScreenAlias.layoutKey) !== "layoutCustom" && fullScreenAlias.layoutCustom !== undefined) {
                     fullScreenAlias.layoutKey = "layoutCustom";
                 }
@@ -166,9 +166,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     buttonClick = async (altKey: boolean, ctrlKey: boolean) => {
-        let maximizedDocs = await DocListCastAsync(this.Document.maximizedDocs);
-        let summarizedDocs = await DocListCastAsync(this.Document.summarizedDocs);
-        let linkDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
+        const maximizedDocs = await DocListCastAsync(this.Document.maximizedDocs);
+        const summarizedDocs = await DocListCastAsync(this.Document.summarizedDocs);
+        const linkDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
         let expandedDocs: Doc[] = [];
         expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs;
         expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs;
@@ -179,7 +179,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             maxLocation = this.Document.maximizeLocation = (!ctrlKey ? !altKey ? maxLocation : (maxLocation !== "inPlace" ? "inPlace" : "onRight") : (maxLocation !== "inPlace" ? "inPlace" : "inTab"));
             if (maxLocation === "inPlace") {
                 expandedDocs.forEach(maxDoc => this.props.addDocument && this.props.addDocument(maxDoc));
-                let scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.layoutDoc.width) / 2, NumCast(this.layoutDoc.height) / 2);
+                const scrpt = this.props.ScreenToLocalTransform().scale(this.props.ContentScaling()).inverse().transformPoint(NumCast(this.layoutDoc.width) / 2, NumCast(this.layoutDoc.height) / 2);
                 DocumentManager.Instance.animateBetweenPoint(scrpt, expandedDocs);
             } else {
                 expandedDocs.forEach(maxDoc => (!this.props.addDocTab(maxDoc, undefined, "close") && this.props.addDocTab(maxDoc, undefined, maxLocation)));
@@ -278,7 +278,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             fieldTemplate.heading = 1;
             fieldTemplate.autoHeight = true;
 
-            let docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: doc.title + "_layout", width: width + 20, height: Math.max(100, height + 45) });
+            const docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: doc.title + "_layout", width: width + 20, height: Math.max(100, height + 45) });
 
             Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate), true);
             Doc.ApplyTemplateTo(docTemplate, dataDoc || doc, "layoutCustom", undefined);
@@ -324,10 +324,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @action
     onDrop = (e: React.DragEvent) => {
-        let text = e.dataTransfer.getData("text/plain");
+        const text = e.dataTransfer.getData("text/plain");
         if (!e.isDefaultPrevented() && text && text.startsWith("<div")) {
-            let oldLayout = this.Document.layout || "";
-            let layout = text.replace("{layout}", oldLayout);
+            const oldLayout = this.Document.layout || "";
+            const layout = text.replace("{layout}", oldLayout);
             this.Document.layout = layout;
             e.stopPropagation();
             e.preventDefault();
@@ -348,11 +348,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @undoBatch
     @action
     makeIntoPortal = async () => {
-        let anchors = await Promise.all(DocListCast(this.Document.links).map(async (d: Doc) => Cast(d.anchor2, Doc)));
+        const anchors = await Promise.all(DocListCast(this.Document.links).map(async (d: Doc) => Cast(d.anchor2, Doc)));
         if (!anchors.find(anchor2 => anchor2 && anchor2.title === this.Document.title + ".portal" ? true : false)) {
-            let portalID = (this.Document.title + ".portal").replace(/^-/, "").replace(/\([0-9]*\)$/, "");
+            const portalID = (this.Document.title + ".portal").replace(/^-/, "").replace(/\([0-9]*\)$/, "");
             DocServer.GetRefField(portalID).then(existingPortal => {
-                let portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.layoutDoc.width || 0) + 10, height: this.layoutDoc.height || 0, title: portalID });
+                const portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.layoutDoc.width || 0) + 10, height: this.layoutDoc.height || 0, title: portalID });
                 DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, portalID, "portal link");
                 this.Document.isButton = true;
             });
@@ -400,7 +400,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         e.preventDefault();
 
         const cm = ContextMenu.Instance;
-        let subitems: ContextMenuProps[] = [];
+        const subitems: ContextMenuProps[] = [];
         subitems.push({ description: "Open Full Screen", event: () => CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(this), icon: "desktop" });
         subitems.push({ description: "Open Tab        ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "inTab"), icon: "folder" });
         subitems.push({ description: "Open Right      ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "onRight"), icon: "caret-square-right" });
@@ -410,8 +410,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" });
 
 
-        let existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
-        let onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+        const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+        const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
         onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
         onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript("toggleDetail(this)"), icon: "window-restore" });
         onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
@@ -425,7 +425,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         });
         !existingOnClick && cm.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
 
-        let funcs: ContextMenuProps[] = [];
+        const funcs: ContextMenuProps[] = [];
         if (this.Document.onDragStart) {
             funcs.push({ description: "Drag an Alias", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) });
             funcs.push({ description: "Drag a Copy", icon: "edit", event: () => this.Document.dragFactory && (this.Document.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) });
@@ -433,8 +433,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             ContextMenu.Instance.addItem({ description: "OnDrag...", subitems: funcs, icon: "asterisk" });
         }
 
-        let existing = ContextMenu.Instance.findByDescription("Layout...");
-        let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : [];
+        const existing = ContextMenu.Instance.findByDescription("Layout...");
+        const layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : [];
         layoutItems.push({ description: this.Document.isBackground ? "As Foreground" : "As Background", event: this.makeBackground, icon: this.Document.lockedPosition ? "unlock" : "lock" });
         if (this.props.DataDoc) {
             layoutItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc!), icon: "concierge-bell" });
@@ -453,8 +453,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
         !existing && cm.addItem({ description: "Layout...", subitems: layoutItems, icon: "compass" });
 
-        let more = ContextMenu.Instance.findByDescription("More...");
-        let moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
+        const more = ContextMenu.Instance.findByDescription("More...");
+        const moreItems: ContextMenuProps[] = more && "subitems" in more ? more.subitems : [];
 
         if (!ClientUtils.RELEASE) {
             // let copies: ContextMenuProps[] = [];
@@ -489,7 +489,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
         runInAction(() => {
             if (!ClientUtils.RELEASE) {
-                let setWriteMode = (mode: DocServer.WriteMode) => {
+                const setWriteMode = (mode: DocServer.WriteMode) => {
                     DocServer.AclsMode = mode;
                     const mode1 = mode;
                     const mode2 = mode === DocServer.WriteMode.Default ? mode : DocServer.WriteMode.Playground;
@@ -503,7 +503,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                     DocServer.setFieldWriteMode("scale", mode2);
                     DocServer.setFieldWriteMode("viewType", mode2);
                 };
-                let aclsMenu: ContextMenuProps[] = [];
+                const aclsMenu: ContextMenuProps[] = [];
                 aclsMenu.push({ description: "Default (write/read all)", event: () => setWriteMode(DocServer.WriteMode.Default), icon: DocServer.AclsMode === DocServer.WriteMode.Default ? "check" : "exclamation" });
                 aclsMenu.push({ description: "Playground (write own/no read)", event: () => setWriteMode(DocServer.WriteMode.Playground), icon: DocServer.AclsMode === DocServer.WriteMode.Playground ? "check" : "exclamation" });
                 aclsMenu.push({ description: "Live Playground (write own/read others)", event: () => setWriteMode(DocServer.WriteMode.LivePlayground), icon: DocServer.AclsMode === DocServer.WriteMode.LivePlayground ? "check" : "exclamation" });
@@ -539,8 +539,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); };
 
     chromeHeight = () => {
-        let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
-        let showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.Document.showTitle);
+        const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
+        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.Document.showTitle);
         return (showTitle ? 25 : 0) + 1;
     }
 
@@ -585,8 +585,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     // if it's a tempoarl link (currently just for Audio), then the audioBox will display the anchor and we don't want to display it here.
     // would be good to generalize this some way.
     isNonTemporalLink = (linkDoc: Doc) => {
-        let anchor = Cast(Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1 : linkDoc.anchor2, Doc) as Doc;
-        let ept = Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1Timecode : linkDoc.anchor2Timecode;
+        const anchor = Cast(Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1 : linkDoc.anchor2, Doc) as Doc;
+        const ept = Doc.AreProtosEqual(this.props.Document, Cast(linkDoc.anchor1, Doc) as Doc) ? linkDoc.anchor1Timecode : linkDoc.anchor2Timecode;
         return anchor.type === DocumentType.AUDIO && NumCast(ept) ? false : true;
     }
 
@@ -651,14 +651,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @action
     handle2PointersMove = (e: TouchEvent) => {
-        let pt1 = e.targetTouches.item(0);
-        let pt2 = e.targetTouches.item(1);
+        const pt1 = e.targetTouches.item(0);
+        const pt2 = e.targetTouches.item(1);
         if (pt1 && pt2 && this.prevPoints.has(pt1.identifier) && this.prevPoints.has(pt2.identifier)) {
-            let oldPoint1 = this.prevPoints.get(pt1.identifier);
-            let oldPoint2 = this.prevPoints.get(pt2.identifier);
-            let pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!);
+            const oldPoint1 = this.prevPoints.get(pt1.identifier);
+            const oldPoint2 = this.prevPoints.get(pt2.identifier);
+            const pinching = InteractionUtils.Pinning(pt1, pt2, oldPoint1!, oldPoint2!);
             if (pinching !== 0) {
-                let newWidth = Math.max(Math.abs(oldPoint1!.clientX - oldPoint2!.clientX), Math.abs(pt1.clientX - pt2.clientX));
+                const newWidth = Math.max(Math.abs(oldPoint1!.clientX - oldPoint2!.clientX), Math.abs(pt1.clientX - pt2.clientX));
                 this.props.Document.width = newWidth;
             }
         }
@@ -679,12 +679,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const localScale = fullDegree;
 
         const animDims = this.Document.animateToDimensions ? Array.from(this.Document.animateToDimensions) : undefined;
-        let animheight = animDims ? animDims[1] : "100%";
-        let animwidth = animDims ? animDims[0] : "100%";
+        const animheight = animDims ? animDims[1] : "100%";
+        const animwidth = animDims ? animDims[0] : "100%";
 
         const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
-        let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
+        const highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
         return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont}
             onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
             onPointerEnter={e => Doc.BrushDoc(this.props.Document)} onPointerLeave={e => Doc.UnBrushDoc(this.props.Document)}
diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx
index 887efc0d5..20afa4565 100644
--- a/src/client/views/nodes/FaceRectangle.tsx
+++ b/src/client/views/nodes/FaceRectangle.tsx
@@ -12,7 +12,7 @@ export default class FaceRectangle extends React.Component<{ rectangle: Rectangl
     }
 
     render() {
-        let rectangle = this.props.rectangle;
+        const rectangle = this.props.rectangle;
         return (
             <div
                 style={{
diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx
index acf1aced3..3c7f1f206 100644
--- a/src/client/views/nodes/FaceRectangles.tsx
+++ b/src/client/views/nodes/FaceRectangles.tsx
@@ -20,10 +20,10 @@ export interface RectangleTemplate {
 export default class FaceRectangles extends React.Component<FaceRectanglesProps> {
 
     render() {
-        let faces = DocListCast(this.props.document.faces);
-        let templates: RectangleTemplate[] = faces.map(faceDoc => {
-            let rectangle = Cast(faceDoc.faceRectangle, Doc) as Doc;
-            let style = {
+        const faces = DocListCast(this.props.document.faces);
+        const templates: RectangleTemplate[] = faces.map(faceDoc => {
+            const rectangle = Cast(faceDoc.faceRectangle, Doc) as Doc;
+            const style = {
                 top: NumCast(rectangle.top),
                 left: NumCast(rectangle.left),
                 width: NumCast(rectangle.width),
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 960b55e3e..2433251b3 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -25,8 +25,8 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
         this._backgroundReaction = reaction(() => this.props.Document.backgroundColor,
             () => {
                 if (this._ref && this._ref.current) {
-                    let col = Utils.fromRGBAstr(getComputedStyle(this._ref.current).backgroundColor);
-                    let colsum = (col.r + col.g + col.b);
+                    const col = Utils.fromRGBAstr(getComputedStyle(this._ref.current).backgroundColor);
+                    const colsum = (col.r + col.g + col.b);
                     if (colsum / col.a > 600 || col.a < 0.25) runInAction(() => this._foregroundColor = "black");
                     else if (colsum / col.a <= 600 || col.a >= .25) runInAction(() => this._foregroundColor = "white");
                 }
@@ -36,8 +36,8 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
         this._backgroundReaction && this._backgroundReaction();
     }
     render() {
-        let referenceDoc = (this.props.Document.dragFactory instanceof Doc ? this.props.Document.dragFactory : this.props.Document);
-        let referenceLayout = Doc.Layout(referenceDoc);
+        const referenceDoc = (this.props.Document.dragFactory instanceof Doc ? this.props.Document.dragFactory : this.props.Document);
+        const referenceLayout = Doc.Layout(referenceDoc);
         return <button className="fontIconBox-outerDiv" title={StrCast(this.props.Document.title)} ref={this._ref}
             style={{
                 background: StrCast(referenceLayout.backgroundColor),
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index a5530f32d..57321de49 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,6 +1,6 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import { faEdit, faSmile, faTextHeight, faUpload } from '@fortawesome/free-solid-svg-icons';
-import _ from "lodash";
+import { isEqual } from "lodash";
 import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction, trace } from "mobx";
 import { observer } from "mobx-react";
 import { baseKeymap } from "prosemirror-commands";
@@ -103,8 +103,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         return html.indexOf("data-pm-slice") !== -1;
     }
     public static GetHref(html: string): string {
-        let parser = new DOMParser();
-        let parsedHtml = parser.parseFromString(html, 'text/html');
+        const parser = new DOMParser();
+        const parsedHtml = parser.parseFromString(html, 'text/html');
         if (parsedHtml.body.childNodes.length === 1 && parsedHtml.body.childNodes[0].childNodes.length === 1 &&
             (parsedHtml.body.childNodes[0].childNodes[0] as any).href) {
             return (parsedHtml.body.childNodes[0].childNodes[0] as any).href;
@@ -126,12 +126,12 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     @undoBatch
     public setFontColor(color: string) {
-        let view = this._editorView!;
+        const view = this._editorView!;
         if (view.state.selection.from === view.state.selection.to) return false;
         if (view.state.selection.to - view.state.selection.from > view.state.doc.nodeSize - 3) {
             this.layoutDoc.color = color;
         }
-        let colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color: color });
+        const colorMark = view.state.schema.mark(view.state.schema.marks.pFontColor, { color: color });
         view.dispatch(view.state.tr.addMark(view.state.selection.from, view.state.selection.to, colorMark));
         return true;
     }
@@ -147,9 +147,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     doLinkOnDeselect() {
         Array.from(this.linkOnDeselect.entries()).map(entry => {
-            let key = entry[0];
-            let value = entry[1];
-            let id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
+            const key = entry[0];
+            const value = entry[1];
+            const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
             DocServer.GetRefField(value).then(doc => {
                 DocServer.GetRefField(id).then(linkDoc => {
                     this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
@@ -164,24 +164,24 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     dispatchTransaction = (tx: Transaction) => {
         if (this._editorView) {
-            let metadata = tx.selection.$from.marks().find((m: Mark) => m.type === schema.marks.metadata);
+            const metadata = tx.selection.$from.marks().find((m: Mark) => m.type === schema.marks.metadata);
             if (metadata) {
-                let range = tx.selection.$from.blockRange(tx.selection.$to);
+                const range = tx.selection.$from.blockRange(tx.selection.$to);
                 let text = range ? tx.doc.textBetween(range.start, range.end) : "";
                 let textEndSelection = tx.selection.to;
                 for (; textEndSelection < range!.end && text[textEndSelection - range!.start] !== " "; textEndSelection++) { }
                 text = text.substr(0, textEndSelection - range!.start);
                 text = text.split(" ")[text.split(" ").length - 1];
-                let split = text.split("::");
+                const split = text.split("::");
                 if (split.length > 1 && split[1]) {
-                    let key = split[0];
-                    let value = split[split.length - 1];
+                    const key = split[0];
+                    const value = split[split.length - 1];
                     this.linkOnDeselect.set(key, value);
 
-                    let id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
+                    const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
                     const link = this._editorView.state.schema.marks.link.create({ href: `http://localhost:1050/doc/${id}`, location: "onRight", title: value });
                     const mval = this._editorView.state.schema.marks.metadataVal.create();
-                    let offset = (tx.selection.to === range!.end - 1 ? -1 : 0);
+                    const offset = (tx.selection.to === range!.end - 1 ? -1 : 0);
                     tx = tx.addMark(textEndSelection - value.length + offset, textEndSelection, link).addMark(textEndSelection - value.length + offset, textEndSelection, mval);
                     this.dataDoc[key] = value;
                 }
@@ -189,7 +189,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             const state = this._editorView.state.apply(tx);
             this._editorView.updateState(state);
 
-            let tsel = this._editorView.state.selection.$from;
+            const tsel = this._editorView.state.selection.$from;
             tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 5000 - 1000)));
             this._applyingChange = true;
             this.extensionDoc && (this.extensionDoc.lastModified = new DateField(new Date(Date.now())));
@@ -202,8 +202,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     updateTitle = () => {
         if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.Document.customTitle) {
-            let str = this._editorView.state.doc.textContent;
-            let titlestr = str.substr(0, Math.min(40, str.length));
+            const str = this._editorView.state.doc.textContent;
+            const titlestr = str.substr(0, Math.min(40, str.length));
             this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
         }
     }
@@ -212,11 +212,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (this._editorView && (this._editorView as any).docView) {
             const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
             const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
-            let res = terms.map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
+            const res = terms.map(term => this.findInNode(this._editorView!, this._editorView!.state.doc, term));
             let tr = this._editorView.state.tr;
-            let flattened: TextSelection[] = [];
+            const flattened: TextSelection[] = [];
             res.map(r => r.map(h => flattened.push(h)));
-            let lastSel = Math.min(flattened.length - 1, this._searchIndex);
+            const lastSel = Math.min(flattened.length - 1, this._searchIndex);
             flattened.forEach((h: TextSelection, ind: number) => tr = tr.addMark(h.from, h.to, ind === lastSel ? activeMark : mark));
             this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex;
             this._editorView.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(flattened[lastSel].from), tr.doc.resolve(flattened[lastSel].to))).scrollIntoView());
@@ -227,13 +227,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (this._editorView && (this._editorView as any).docView) {
             const mark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight);
             const activeMark = this._editorView.state.schema.mark(this._editorView.state.schema.marks.search_highlight, { selected: true });
-            let end = this._editorView.state.doc.nodeSize - 2;
+            const end = this._editorView.state.doc.nodeSize - 2;
             this._editorView.dispatch(this._editorView.state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark));
         }
     }
     setAnnotation = (start: number, end: number, mark: Mark, opened: boolean, keep: boolean = false) => {
-        let view = this._editorView!;
-        let nmark = view.state.schema.marks.user_mark.create({ ...mark.attrs, userid: keep ? Doc.CurrentUserEmail : mark.attrs.userid, opened: opened });
+        const view = this._editorView!;
+        const nmark = view.state.schema.marks.user_mark.create({ ...mark.attrs, userid: keep ? Doc.CurrentUserEmail : mark.attrs.userid, opened: opened });
         view.dispatch(view.state.tr.removeMark(start, end, nmark).addMark(start, end, nmark));
     }
     protected createDropTarget = (ele: HTMLDivElement) => {
@@ -266,16 +266,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 e.stopPropagation();
                 // embed document when dragging with a userDropAction or an embedDoc flag set
             } else if (de.data.userDropAction || de.data.embedDoc) {
-                let target = de.data.droppedDocuments[0];
+                const target = de.data.droppedDocuments[0];
                 // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title);
                 // if (link) {
                 target.fitToBox = true;
-                let node = schema.nodes.dashDoc.create({
+                const node = schema.nodes.dashDoc.create({
                     width: target[WidthSym](), height: target[HeightSym](),
                     title: "dashDoc", docid: target[Id],
                     float: "right"
                 });
-                let view = this._editorView!;
+                const view = this._editorView!;
                 view.dispatch(view.state.tr.insert(view.posAtCoords({ left: de.x, top: de.y })!.pos, node));
                 this.tryUpdateHeight();
                 e.stopPropagation();
@@ -292,7 +292,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (node.isBlock) {
             // tslint:disable-next-line: prefer-for-of
             for (let i = 0; i < (context.content as any).content.length; i++) {
-                let result = this.getNodeEndpoints((context.content as any).content[i], node);
+                const result = this.getNodeEndpoints((context.content as any).content[i], node);
                 if (result) {
                     return {
                         from: result.from + offset + (context.type.name === "doc" ? 0 : 1),
@@ -313,9 +313,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         let ret: TextSelection[] = [];
 
         if (node.isTextblock) {
-            let index = 0, foundAt, ep = this.getNodeEndpoints(pm.state.doc, node);
+            let index = 0, foundAt;
+            const ep = this.getNodeEndpoints(pm.state.doc, node);
             while (ep && (foundAt = node.textContent.slice(index).search(RegExp(find, "i"))) > -1) {
-                let sel = new TextSelection(pm.state.doc.resolve(ep.from + index + foundAt + 1), pm.state.doc.resolve(ep.from + index + foundAt + find.length + 1));
+                const sel = new TextSelection(pm.state.doc.resolve(ep.from + index + foundAt + 1), pm.state.doc.resolve(ep.from + index + foundAt + find.length + 1));
                 ret.push(sel);
                 index = index + foundAt + find.length;
             }
@@ -348,13 +349,13 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         }
         if (FormattedTextBox._highlights.indexOf("By Recent Minute") !== -1) {
             addStyleSheetRule(FormattedTextBox._userStyleSheet, "userMark-" + Doc.CurrentUserEmail.replace(".", "").replace("@", ""), { opacity: "0.1" });
-            let min = Math.round(Date.now() / 1000 / 60);
+            const min = Math.round(Date.now() / 1000 / 60);
             numberRange(10).map(i => addStyleSheetRule(FormattedTextBox._userStyleSheet, "userMark-min-" + (min - i), { opacity: ((10 - i - 1) / 10).toString() }));
             setTimeout(() => this.updateHighlights());
         }
         if (FormattedTextBox._highlights.indexOf("By Recent Hour") !== -1) {
             addStyleSheetRule(FormattedTextBox._userStyleSheet, "userMark-" + Doc.CurrentUserEmail.replace(".", "").replace("@", ""), { opacity: "0.1" });
-            let hr = Math.round(Date.now() / 1000 / 60 / 60);
+            const hr = Math.round(Date.now() / 1000 / 60 / 60);
             numberRange(10).map(i => addStyleSheetRule(FormattedTextBox._userStyleSheet, "userMark-hr-" + (hr - i), { opacity: ((10 - i - 1) / 10).toString() }));
         }
     }
@@ -362,7 +363,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     toggleSidebar = () => this.props.Document.sidebarWidthPercent = StrCast(this.props.Document.sidebarWidthPercent, "0%") === "0%" ? "25%" : "0%";
 
     specificContextMenu = (e: React.MouseEvent): void => {
-        let funcs: ContextMenuProps[] = [];
+        const funcs: ContextMenuProps[] = [];
         funcs.push({ description: "Toggle Sidebar", event: () => { e.stopPropagation(); this.toggleSidebar(); }, icon: "expand-arrows-alt" });
         funcs.push({ description: "Record Bullet", event: () => { e.stopPropagation(); this.recordBullet(); }, icon: "expand-arrows-alt" });
         ["My Text", "Text from Others", "Todo Items", "Important Items", "Ignore Items", "Disagree Items", "By Recent Minute", "By Recent Hour"].forEach(option =>
@@ -403,8 +404,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     recordBullet = async () => {
-        let completedCue = "end session";
-        let results = await DictationManager.Controls.listen({
+        const completedCue = "end session";
+        const results = await DictationManager.Controls.listen({
             interimHandler: this.setCurrentBulletContent,
             continuous: { indefinite: false },
             terminators: [completedCue, "bullet", "next"]
@@ -420,20 +421,20 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     setCurrentBulletContent = (value: string) => {
         if (this._editorView) {
             let state = this._editorView.state;
-            let from = state.selection.from;
-            let to = state.selection.to;
+            const from = state.selection.from;
+            const to = state.selection.to;
             this._editorView.dispatch(state.tr.insertText(value, from, to));
             state = this._editorView.state;
-            let updated = TextSelection.create(state.doc, from, from + value.length);
+            const updated = TextSelection.create(state.doc, from, from + value.length);
             this._editorView.dispatch(state.tr.setSelection(updated));
         }
     }
 
     nextBullet = (pos: number) => {
         if (this._editorView) {
-            let frag = Fragment.fromArray(this.newListItems(2));
+            const frag = Fragment.fromArray(this.newListItems(2));
             if (this._editorView.state.doc.resolve(pos).depth >= 2) {
-                let slice = new Slice(frag, 2, 2);
+                const slice = new Slice(frag, 2, 2);
                 let state = this._editorView.state;
                 this._editorView.dispatch(state.tr.step(new ReplaceStep(pos, pos, slice)));
                 pos += 4;
@@ -471,8 +472,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     componentDidMount() {
-        this.pullFromGoogleDoc(this.checkState);
-        this.dataDoc[GoogleRef] && this.dataDoc.unchanged && runInAction(() => DocumentDecorations.Instance.isAnimatingFetch = true);
+        if (DocumentButtonBar.Instance) {
+            this.pullFromGoogleDoc(this.checkState);
+            this.dataDoc[GoogleRef] && this.dataDoc.unchanged && runInAction(() => DocumentButtonBar.Instance.isAnimatingFetch = true);
+        }
 
         this._reactionDisposer = reaction(
             () => {
@@ -481,7 +484,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             },
             incomingValue => {
                 if (this._editorView && !this._applyingChange) {
-                    let updatedState = JSON.parse(incomingValue);
+                    const updatedState = JSON.parse(incomingValue);
                     this._editorView.updateState(EditorState.fromJSON(this.config, updatedState));
                     this.tryUpdateHeight();
                 }
@@ -493,7 +496,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             () => {
                 if (!DocumentButtonBar.hasPulledHack) {
                     DocumentButtonBar.hasPulledHack = true;
-                    let unchanged = this.dataDoc.unchanged;
+                    const unchanged = this.dataDoc.unchanged;
                     this.pullFromGoogleDoc(unchanged ? this.checkState : this.updateState);
                 }
             }
@@ -514,7 +517,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             () => this.tryUpdateHeight()
         );
 
-
         this.setupEditor(this.config, this.dataDoc, this.props.fieldKey);
 
         this._searchReactionDisposer = reaction(() => {
@@ -528,10 +530,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             }
         }, { fireImmediately: true });
 
-
         this._rulesReactionDisposer = reaction(() => {
-            let ruleProvider = this.props.ruleProvider;
-            let heading = NumCast(this.layoutDoc.heading);
+            const ruleProvider = this.props.ruleProvider;
+            const heading = NumCast(this.layoutDoc.heading);
             if (ruleProvider instanceof Doc) {
                 return {
                     align: StrCast(ruleProvider["ruleAlign_" + heading], ""),
@@ -547,7 +548,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 rules && setTimeout(() => {
                     const view = this._editorView!;
                     if (this._proseRef) {
-                        let n = new NodeSelection(view.state.doc.resolve(0));
+                        const n = new NodeSelection(view.state.doc.resolve(0));
                         if (this._editorView!.state.doc.textContent === "") {
                             view.dispatch(view.state.tr.setSelection(new TextSelection(view.state.doc.resolve(0), view.state.doc.resolve(2))).
                                 replaceSelectionWith(this._editorView!.state.schema.nodes.paragraph.create({ align: rules.align }), true));
@@ -562,10 +563,10 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         this._scrollToRegionReactionDisposer = reaction(
             () => StrCast(this.layoutDoc.scrollToLinkID),
             async (scrollToLinkID) => {
-                let findLinkFrag = (frag: Fragment, editor: EditorView) => {
+                const findLinkFrag = (frag: Fragment, editor: EditorView) => {
                     const nodes: Node[] = [];
                     frag.forEach((node, index) => {
-                        let examinedNode = findLinkNode(node, editor);
+                        const examinedNode = findLinkNode(node, editor);
                         if (examinedNode && examinedNode.textContent) {
                             nodes.push(examinedNode);
                             start += index;
@@ -573,7 +574,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                     });
                     return { frag: Fragment.fromArray(nodes), start: start };
                 };
-                let findLinkNode = (node: Node, editor: EditorView) => {
+                const findLinkNode = (node: Node, editor: EditorView) => {
                     if (!node.isText) {
                         const content = findLinkFrag(node.content, editor);
                         return node.copy(content.frag);
@@ -585,8 +586,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
                 let start = -1;
                 if (this._editorView && scrollToLinkID) {
-                    let editor = this._editorView;
-                    let ret = findLinkFrag(editor.state.doc.content, editor);
+                    const editor = this._editorView;
+                    const ret = findLinkFrag(editor.state.doc.content, editor);
 
                     if (ret.frag.size > 2 && ret.start >= 0) {
                         let selection = TextSelection.near(editor.state.doc.resolve(ret.start)); // default to near the start
@@ -610,28 +611,28 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     pushToGoogleDoc = async () => {
         this.pullFromGoogleDoc(async (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => {
-            let modes = GoogleApiClientUtils.Docs.WriteMode;
+            const modes = GoogleApiClientUtils.Docs.WriteMode;
             let mode = modes.Replace;
             let reference: Opt<GoogleApiClientUtils.Docs.Reference> = Cast(this.dataDoc[GoogleRef], "string");
             if (!reference) {
                 mode = modes.Insert;
                 reference = { title: StrCast(this.dataDoc.title) };
             }
-            let redo = async () => {
+            const redo = async () => {
                 if (this._editorView && reference) {
-                    let content = await RichTextUtils.GoogleDocs.Export(this._editorView.state);
-                    let response = await GoogleApiClientUtils.Docs.write({ reference, content, mode });
+                    const content = await RichTextUtils.GoogleDocs.Export(this._editorView.state);
+                    const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode });
                     response && (this.dataDoc[GoogleRef] = response.documentId);
-                    let pushSuccess = response !== undefined && !("errors" in response);
+                    const pushSuccess = response !== undefined && !("errors" in response);
                     dataDoc.unchanged = pushSuccess;
                     DocumentButtonBar.Instance.startPushOutcome(pushSuccess);
                 }
             };
-            let undo = () => {
+            const undo = () => {
                 if (!exportState) {
                     return;
                 }
-                let content: GoogleApiClientUtils.Docs.Content = {
+                const content: GoogleApiClientUtils.Docs.Content = {
                     text: exportState.text,
                     requests: []
                 };
@@ -645,8 +646,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     pullFromGoogleDoc = async (handler: PullHandler) => {
-        let dataDoc = this.dataDoc;
-        let documentId = StrCast(dataDoc[GoogleRef]);
+        const dataDoc = this.dataDoc;
+        const documentId = StrCast(dataDoc[GoogleRef]);
         let exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>;
         if (documentId) {
             exportState = await RichTextUtils.GoogleDocs.Import(documentId, dataDoc);
@@ -661,8 +662,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             dataDoc.data = new RichTextField(JSON.stringify(exportState.state.toJSON()));
             setTimeout(() => {
                 if (this._editorView) {
-                    let state = this._editorView.state;
-                    let end = state.doc.content.size - 1;
+                    const state = this._editorView.state;
+                    const end = state.doc.content.size - 1;
                     this._editorView.dispatch(state.tr.setSelection(TextSelection.create(state.doc, end, end)));
                 }
             }, 0);
@@ -677,9 +678,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     checkState = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => {
         if (exportState && this._editorView) {
-            let equalContent = _.isEqual(this._editorView.state.doc, exportState.state.doc);
-            let equalTitles = dataDoc.title === exportState.title;
-            let unchanged = equalContent && equalTitles;
+            const equalContent = isEqual(this._editorView.state.doc, exportState.state.doc);
+            const equalTitles = dataDoc.title === exportState.title;
+            const unchanged = equalContent && equalTitles;
             dataDoc.unchanged = unchanged;
             DocumentButtonBar.Instance.setPullState(unchanged);
         }
@@ -707,7 +708,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => {
-        let cbe = event as ClipboardEvent;
+        const cbe = event as ClipboardEvent;
         const pdfDocId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfOrigin");
         const pdfRegionId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfRegion");
         if (pdfDocId && pdfRegionId) {
@@ -717,18 +718,18 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                         setTimeout(async () => {
                             const extension = Doc.fieldExtensionDoc(pdfDoc, "data");
                             if (extension) {
-                                let targetAnnotations = await DocListCastAsync(extension.annotations);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
+                                const targetAnnotations = await DocListCastAsync(extension.annotations);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
                                 targetAnnotations && targetAnnotations.push(pdfRegion);
                             }
                         });
 
-                        let link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
+                        const link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
                         if (link) {
                             cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
-                            let linkId = link[Id];
-                            let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
+                            const linkId = link[Id];
+                            const frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
                             slice = new Slice(frag, slice.openStart, slice.openEnd);
-                            var tr = view.state.tr.replaceSelection(slice);
+                            const tr = view.state.tr.replaceSelection(slice);
                             view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
                         }
                     }
@@ -758,11 +759,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     private setupEditor(config: any, doc: Doc, fieldKey: string) {
-        let field = doc ? Cast(doc[fieldKey], RichTextField) : undefined;
+        const field = doc ? Cast(doc[fieldKey], RichTextField) : undefined;
         let startup = StrCast(doc.documentText);
         startup = startup.startsWith("@@@") ? startup.replace("@@@", "") : "";
         if (!field && doc) {
-            let text = StrCast(doc[fieldKey]);
+            const text = StrCast(doc[fieldKey]);
             if (text) {
                 startup = text;
             } else if (Cast(doc[fieldKey], "number")) {
@@ -770,16 +771,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             }
         }
         if (this._proseRef) {
-            let self = this;
+            const self = this;
             this._editorView && this._editorView.destroy();
             this._editorView = new EditorView(this._proseRef, {
                 state: field && field.Data ? EditorState.fromJSON(config, JSON.parse(field.Data)) : EditorState.create(config),
                 handleScrollToSelection: (editorView) => {
-                    let ref = editorView.domAtPos(editorView.state.selection.from);
+                    const ref = editorView.domAtPos(editorView.state.selection.from);
                     let refNode = ref.node as any;
                     while (refNode && !("getBoundingClientRect" in refNode)) refNode = refNode.parentElement;
-                    let r1 = refNode && refNode.getBoundingClientRect();
-                    let r3 = self._ref.current!.getBoundingClientRect();
+                    const r1 = refNode && refNode.getBoundingClientRect();
+                    const r3 = self._ref.current!.getBoundingClientRect();
                     if (r1.top < r3.top || r1.top > r3.bottom) {
                         r1 && (self._ref.current!.scrollTop += (r1.top - r3.top) * self.props.ScreenToLocalTransform().Scale);
                     }
@@ -803,7 +804,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             }
         }
 
-        let selectOnLoad = this.props.Document[Id] === FormattedTextBox.SelectOnLoad;
+        const selectOnLoad = this.props.Document[Id] === FormattedTextBox.SelectOnLoad;
         if (selectOnLoad) {
             FormattedTextBox.SelectOnLoad = "";
             this.props.select(false);
@@ -838,7 +839,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
     onPointerDown = (e: React.PointerEvent): void => {
         FormattedTextBoxComment.textBox = this;
-        let pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
+        const pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY });
         pos && (this._nodeClicked = this._editorView!.state.doc.nodeAt(pos.pos));
         if (this.props.onClick && e.button === 0) {
             e.preventDefault();
@@ -923,16 +924,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     hitBulletTargets(x: number, y: number, offsetX: number, select: boolean, highlightOnly = false) {
         clearStyleSheetRules(FormattedTextBox._bulletStyleSheet);
         if (this.props.isSelected(true) && offsetX < 40) {
-            let pos = this._editorView!.posAtCoords({ left: x, top: y });
+            const pos = this._editorView!.posAtCoords({ left: x, top: y });
             if (pos && pos.pos > 0) {
-                let node = this._editorView!.state.doc.nodeAt(pos.pos);
-                let node2 = node?.type === schema.nodes.paragraph ? this._editorView!.state.doc.nodeAt(pos.pos - 1) : undefined;
+                const node = this._editorView!.state.doc.nodeAt(pos.pos);
+                const node2 = node?.type === schema.nodes.paragraph ? this._editorView!.state.doc.nodeAt(pos.pos - 1) : undefined;
                 if ((node === this._nodeClicked || highlightOnly) && (node2?.type === schema.nodes.ordered_list || node2?.type === schema.nodes.list_item)) {
-                    let hit = this._editorView!.domAtPos(pos.pos).node as any;   // let beforeEle = document.querySelector("." + hit.className) as Element;
-                    let before = hit ? window.getComputedStyle(hit, ':before') : undefined;
-                    let beforeWidth = before ? Number(before.getPropertyValue('width').replace("px", "")) : undefined;
+                    const hit = this._editorView!.domAtPos(pos.pos).node as any;   // let beforeEle = document.querySelector("." + hit.className) as Element;
+                    const before = hit ? window.getComputedStyle(hit, ':before') : undefined;
+                    const beforeWidth = before ? Number(before.getPropertyValue('width').replace("px", "")) : undefined;
                     if (beforeWidth && offsetX < beforeWidth * .9) {
-                        let ol = this._editorView!.state.doc.nodeAt(pos.pos - 2) ? this._editorView!.state.doc.nodeAt(pos.pos - 2) : undefined;
+                        const ol = this._editorView!.state.doc.nodeAt(pos.pos - 2) ? this._editorView!.state.doc.nodeAt(pos.pos - 2) : undefined;
                         if (ol?.type === schema.nodes.ordered_list && select) {
                             if (!highlightOnly) {
                                 this._editorView!.dispatch(this._editorView!.state.tr.setSelection(new NodeSelection(this._editorView!.state.doc.resolve(pos.pos - 2))));
@@ -953,11 +954,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     onMouseUp = (e: React.MouseEvent): void => {
         e.stopPropagation();
 
-        let view = this._editorView as any;
+        const view = this._editorView as any;
         // this interposes on prosemirror's upHandler to prevent prosemirror's up from invoked multiple times when there 
         // are nested prosemirrors.  We only want the lowest level prosemirror to be invoked.
         if (view.mouseDown) {
-            let originalUpHandler = view.mouseDown.up;
+            const originalUpHandler = view.mouseDown.up;
             view.root.removeEventListener("mouseup", originalUpHandler);
             view.mouseDown.up = (e: MouseEvent) => {
                 !(e as any).formattedHandled && originalUpHandler(e);
@@ -969,7 +970,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     tooltipTextMenuPlugin() {
-        let self = FormattedTextBox;
+        const self = FormattedTextBox;
         return new Plugin({
             view(newView) {
                 return self.ToolTipTextMenu = FormattedTextBox.getToolTip(newView);
@@ -978,7 +979,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     }
 
     tooltipLinkingMenuPlugin() {
-        let myprops = this.props;
+        const myprops = this.props;
         return new Plugin({
             view(_editorView) {
                 return new TooltipLinkingMenu(_editorView, myprops);
@@ -1001,7 +1002,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         if (e.key === "Tab" || e.key === "Enter") {
             e.preventDefault();
         }
-        let mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) });
+        const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.round(Date.now() / 1000 / 5) });
         this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark.create({})).addStoredMark(mark));
 
         if (!this._undoTyping) {
@@ -1018,8 +1019,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
         const scrollHeight = this._ref.current?.scrollHeight;
         if (!this.layoutDoc.animateToPos && this.layoutDoc.autoHeight && scrollHeight &&
             getComputedStyle(this._ref.current!.parentElement!).top === "0px") {  // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
-            let nh = this.Document.isTemplateField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
-            let dh = NumCast(this.layoutDoc.height, 0);
+            const nh = this.Document.isTemplateField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
+            const dh = NumCast(this.layoutDoc.height, 0);
             this.layoutDoc.height = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
             this.dataDoc.nativeHeight = nh ? scrollHeight : undefined;
         }
@@ -1030,8 +1031,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     @computed get annotationsKey() { return "annotations"; }
     render() {
         TraceMobx();
-        let rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
-        let interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground;
+        const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
+        const interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground;
         if (this.props.isSelected()) {
             FormattedTextBox.ToolTipTextMenu!.updateFromDash(this._editorView!, undefined, this.props);
         } else if (FormattedTextBoxComment.textBox === this) {
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index c076fd34a..2ec30e3b3 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -81,7 +81,7 @@ export class FormattedTextBoxComment {
             FormattedTextBoxComment.tooltip.style.display = "none";
             FormattedTextBoxComment.tooltip.appendChild(FormattedTextBoxComment.tooltipInput);
             FormattedTextBoxComment.tooltip.onpointerdown = (e: PointerEvent) => {
-                let keep = e.target && (e.target as any).type === "checkbox" ? true : false;
+                const keep = e.target && (e.target as any).type === "checkbox" ? true : false;
                 const textBox = FormattedTextBoxComment.textBox;
                 if (FormattedTextBoxComment.linkDoc && !keep && textBox) {
                     DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
@@ -113,7 +113,7 @@ export class FormattedTextBoxComment {
     }
 
     static update(view: EditorView, lastState?: EditorState) {
-        let state = view.state;
+        const state = view.state;
         // Don't do anything if the document/selection didn't change
         if (lastState && lastState.doc.eq(state.doc) &&
             lastState.selection.eq(state.selection)) {
@@ -136,11 +136,11 @@ export class FormattedTextBoxComment {
         // this section checks to see if the insertion point is over text entered by a different user.  If so, it sets ths comment text to indicate the user and the modification date
         if (state.selection.$from) {
             nbef = findStartOfMark(state.selection.$from, view, findOtherUserMark);
-            let naft = findEndOfMark(state.selection.$from, view, findOtherUserMark);
-            let noselection = view.state.selection.$from === view.state.selection.$to;
+            const naft = findEndOfMark(state.selection.$from, view, findOtherUserMark);
+            const noselection = view.state.selection.$from === view.state.selection.$to;
             let child: any = null;
             state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
-            let mark = child && findOtherUserMark(child.marks);
+            const mark = child && findOtherUserMark(child.marks);
             if (mark && child && (nbef || naft) && (!mark.attrs.opened || noselection)) {
                 FormattedTextBoxComment.SetState(FormattedTextBoxComment.textBox, mark.attrs.opened, state.selection.$from.pos - nbef, state.selection.$from.pos + naft, mark);
             }
@@ -153,10 +153,10 @@ export class FormattedTextBoxComment {
         // this checks if the selection is a hyperlink.  If so, it displays the target doc's text for internal links, and the url of the target for external links. 
         if (set === "none" && state.selection.$from) {
             nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
-            let naft = findEndOfMark(state.selection.$from, view, findLinkMark);
+            const naft = findEndOfMark(state.selection.$from, view, findLinkMark);
             let child: any = null;
             state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
-            let mark = child && findLinkMark(child.marks);
+            const mark = child && findLinkMark(child.marks);
             if (mark && child && nbef && naft) {
                 FormattedTextBoxComment.tooltipText.textContent = "external => " + mark.attrs.href;
                 if (mark.attrs.href.startsWith("https://en.wikipedia.org/wiki/")) {
@@ -167,7 +167,7 @@ export class FormattedTextBoxComment {
                 }
                 (FormattedTextBoxComment.tooltipText as any).href = mark.attrs.href;
                 if (mark.attrs.href.indexOf(Utils.prepend("/doc/")) === 0) {
-                    let docTarget = mark.attrs.href.replace(Utils.prepend("/doc/"), "").split("?")[0];
+                    const docTarget = mark.attrs.href.replace(Utils.prepend("/doc/"), "").split("?")[0];
                     docTarget && DocServer.GetRefField(docTarget).then(linkDoc => {
                         if (linkDoc instanceof Doc) {
                             FormattedTextBoxComment.linkDoc = linkDoc;
@@ -210,12 +210,12 @@ export class FormattedTextBoxComment {
         if (set !== "none") {
             // These are in screen coordinates
             // let start = view.coordsAtPos(state.selection.from), end = view.coordsAtPos(state.selection.to);
-            let start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef);
+            const start = view.coordsAtPos(state.selection.from - nbef), end = view.coordsAtPos(state.selection.from - nbef);
             // The box in which the tooltip is positioned, to use as base
-            let box = (document.getElementById("mainView-container") as any).getBoundingClientRect();
+            const box = (document.getElementById("mainView-container") as any).getBoundingClientRect();
             // Find a center-ish x position from the selection endpoints (when
             // crossing lines, end may be more to the left)
-            let left = Math.max((start.left + end.left) / 2, start.left + 3);
+            const left = Math.max((start.left + end.left) / 2, start.left + 3);
             FormattedTextBoxComment.tooltip.style.left = (left - box.left) + "px";
             FormattedTextBoxComment.tooltip.style.bottom = (box.bottom - start.top) + "px";
         }
diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx
index 60f547b1e..9462ff024 100644
--- a/src/client/views/nodes/IconBox.tsx
+++ b/src/client/views/nodes/IconBox.tsx
@@ -51,7 +51,7 @@ export class IconBox extends React.Component<FieldViewProps> {
     }
 
     public static DocumentIcon(layout: string) {
-        let button = layout.indexOf("PDFBox") !== -1 ? faFilePdf :
+        const button = layout.indexOf("PDFBox") !== -1 ? faFilePdf :
             layout.indexOf("ImageBox") !== -1 ? faImage :
                 layout.indexOf("Formatted") !== -1 ? faStickyNote :
                     layout.indexOf("Video") !== -1 ? faFilm :
@@ -65,14 +65,14 @@ export class IconBox extends React.Component<FieldViewProps> {
     }
 
     specificContextMenu = (): void => {
-        let cm = ContextMenu.Instance;
+        const cm = ContextMenu.Instance;
         cm.addItem({ description: this.props.Document.hideLabel ? "Show label with icon" : "Remove label from icon", event: this.setLabelField, icon: "tag" });
         if (!this.props.Document.hideLabel) {
             cm.addItem({ description: "Use Target Title", event: () => IconBox.AutomaticTitle(this.props.Document), icon: "text-height" });
         }
     }
     render() {
-        let label = this.props.Document.hideLabel ? "" : this.props.Document.title;
+        const label = this.props.Document.hideLabel ? "" : this.props.Document.title;
         return (
             <div className="iconBox-container" onContextMenu={this.specificContextMenu}>
                 {this.minimizedIcon}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c283e4f21..b4a51657f 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -28,8 +28,8 @@ import { documentSchema } from '../../../new_fields/documentSchemas';
 import { Id } from '../../../new_fields/FieldSymbols';
 import { TraceMobx } from '../../../new_fields/util';
 import { SelectionManager } from '../../util/SelectionManager';
-var requestImageSize = require('../../util/request-image-size');
-var path = require('path');
+const requestImageSize = require('../../util/request-image-size');
+const path = require('path');
 const { Howl } = require('howler');
 
 
@@ -88,7 +88,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     recordAudioAnnotation = () => {
         let gumStream: any;
         let recorder: any;
-        let self = this;
+        const self = this;
         const extensionDoc = this.extensionDoc;
         extensionDoc && navigator.mediaDevices.getUserMedia({
             audio: true
@@ -105,9 +105,9 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 const files = await res.json();
                 const url = Utils.prepend(files[0].path);
                 // upload to server with known URL 
-                let audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", width: 200, height: 32 });
+                const audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", width: 200, height: 32 });
                 audioDoc.treeViewExpandedView = "layout";
-                let audioAnnos = Cast(extensionDoc.audioAnnotations, listSpec(Doc));
+                const audioAnnos = Cast(extensionDoc.audioAnnotations, listSpec(Doc));
                 if (audioAnnos === undefined) {
                     extensionDoc.audioAnnotations = new List([audioDoc]);
                 } else {
@@ -126,10 +126,10 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     @undoBatch
     rotate = action(() => {
-        let nw = this.Document.nativeWidth;
-        let nh = this.Document.nativeHeight;
-        let w = this.Document.width;
-        let h = this.Document.height;
+        const nw = this.Document.nativeWidth;
+        const nh = this.Document.nativeHeight;
+        const w = this.Document.width;
+        const h = this.Document.height;
         this.Document.rotation = ((this.Document.rotation || 0) + 90) % 360;
         this.Document.nativeWidth = nh;
         this.Document.nativeHeight = nw;
@@ -140,12 +140,12 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     specificContextMenu = (e: React.MouseEvent): void => {
         const field = Cast(this.Document[this.props.fieldKey], ImageField);
         if (field) {
-            let funcs: ContextMenuProps[] = [];
+            const funcs: ContextMenuProps[] = [];
             funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" });
             funcs.push({ description: "Rotate", event: this.rotate, icon: "expand-arrows-alt" });
 
-            let existingAnalyze = ContextMenu.Instance.findByDescription("Analyzers...");
-            let modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : [];
+            const existingAnalyze = ContextMenu.Instance.findByDescription("Analyzers...");
+            const modes: ContextMenuProps[] = existingAnalyze && "subitems" in existingAnalyze ? existingAnalyze.subitems : [];
             modes.push({ description: "Generate Tags", event: this.generateMetadata, icon: "tag" });
             modes.push({ description: "Find Faces", event: this.extractFaces, icon: "camera" });
             !existingAnalyze && ContextMenu.Instance.addItem({ description: "Analyzers...", subitems: modes, icon: "hand-point-right" });
@@ -155,8 +155,8 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     }
 
     extractFaces = () => {
-        let converter = (results: any) => {
-            let faceDocs = new List<Doc>();
+        const converter = (results: any) => {
+            const faceDocs = new List<Doc>();
             results.reduce((face: CognitiveServices.Image.Face, faceDocs: List<Doc>) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!), new List<Doc>());
             return faceDocs;
         };
@@ -164,12 +164,12 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     }
 
     generateMetadata = (threshold: Confidence = Confidence.Excellent) => {
-        let converter = (results: any) => {
-            let tagDoc = new Doc;
-            let tagsList = new List();
+        const converter = (results: any) => {
+            const tagDoc = new Doc;
+            const tagsList = new List();
             results.tags.map((tag: Tag) => {
                 tagsList.push(tag.name);
-                let sanitized = tag.name.replace(" ", "_");
+                const sanitized = tag.name.replace(" ", "_");
                 tagDoc[sanitized] = ComputedField.MakeFunction(`(${tag.confidence} >= this.confidence) ? ${tag.confidence} : "${ComputedField.undefined}"`);
             });
             this.extensionDoc && (this.extensionDoc.generatedTags = tagsList);
@@ -181,7 +181,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     }
 
     @computed private get url() {
-        let data = Cast(this.dataDoc[this.props.fieldKey], ImageField);
+        const data = Cast(this.dataDoc[this.props.fieldKey], ImageField);
         return data ? data.url.href : undefined;
     }
 
@@ -194,7 +194,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         } else if (!(lower.endsWith(".png") || lower.endsWith(".jpg") || lower.endsWith(".jpeg"))) {
             return url.href;//Why is this here
         }
-        let ext = path.extname(url.href);
+        const ext = path.extname(url.href);
         const suffix = this.props.renderDepth < 1 ? "_o" : this._curSuffix;
         return url.href.replace(ext, suffix + ext);
     }
@@ -208,7 +208,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         if (this._curSuffix === "_l") this._largeRetryCount++;
     }
     @action onError = () => {
-        let timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount;
+        const timeout = this._curSuffix === "_s" ? this._smallRetryCount : this._curSuffix === "_m" ? this._mediumRetryCount : this._largeRetryCount;
         if (timeout < 10) {
             setTimeout(this.retryPath, Math.min(10000, timeout * 5));
         }
@@ -218,9 +218,9 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     resize = (srcpath: string) => {
         requestImageSize(srcpath)
             .then((size: any) => {
-                let rotation = NumCast(this.dataDoc.rotation) % 180;
-                let realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
-                let aspect = realsize.height / realsize.width;
+                const rotation = NumCast(this.dataDoc.rotation) % 180;
+                const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
+                const aspect = realsize.height / realsize.width;
                 if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) {
                     setTimeout(action(() => {
                         this.Document.height = this.Document[WidthSym]() * aspect;
@@ -234,9 +234,9 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     fadesize = (srcpath: string) => {
         requestImageSize(srcpath)
             .then((size: any) => {
-                let rotation = NumCast(this.dataDoc.rotation) % 180;
-                let realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
-                let aspect = realsize.height / realsize.width;
+                const rotation = NumCast(this.dataDoc.rotation) % 180;
+                const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
+                const aspect = realsize.height / realsize.width;
                 if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) {
                     setTimeout(action(() => {
                         this.Document.height = this.Document[WidthSym]() * aspect;
@@ -250,10 +250,10 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     @action
     onPointerEnter = () => {
-        let self = this;
-        let audioAnnos = this.extensionDoc && DocListCast(this.extensionDoc.audioAnnotations);
+        const self = this;
+        const audioAnnos = this.extensionDoc && DocListCast(this.extensionDoc.audioAnnotations);
         if (audioAnnos && audioAnnos.length && this._audioState === 0) {
-            let anno = audioAnnos[Math.floor(Math.random() * audioAnnos.length)];
+            const anno = audioAnnos[Math.floor(Math.random() * audioAnnos.length)];
             anno.data instanceof AudioField && new Howl({
                 src: [anno.data.url.href],
                 format: ["mp3"],
@@ -289,32 +289,32 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         const extensionDoc = this.extensionDoc;
         if (!extensionDoc) return (null);
         // let transform = this.props.ScreenToLocalTransform().inverse();
-        let pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
+        const pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
         // var [sptX, sptY] = transform.transformPoint(0, 0);
         // let [bptX, bptY] = transform.transformPoint(pw, this.props.PanelHeight());
         // let w = bptX - sptX;
 
-        let nativeWidth = (this.Document.nativeWidth || pw);
-        let nativeHeight = (this.Document.nativeHeight || 1);
+        const nativeWidth = (this.Document.nativeWidth || pw);
+        const nativeHeight = (this.Document.nativeHeight || 1);
         let paths = [[Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png"), nativeWidth / nativeHeight]];
         // this._curSuffix = "";
         // if (w > 20) {
-        let alts = DocListCast(extensionDoc.Alternates);
-        let altpaths = alts.filter(doc => doc.data instanceof ImageField).map(doc => [this.choosePath((doc.data as ImageField).url), doc[WidthSym]() / doc[HeightSym]()]);
-        let field = this.dataDoc[this.props.fieldKey];
+        const alts = DocListCast(extensionDoc.Alternates);
+        const altpaths = alts.filter(doc => doc.data instanceof ImageField).map(doc => [this.choosePath((doc.data as ImageField).url), doc[WidthSym]() / doc[HeightSym]()]);
+        const field = this.dataDoc[this.props.fieldKey];
         // if (w < 100 && this._smallRetryCount < 10) this._curSuffix = "_s";
         // else if (w < 600 && this._mediumRetryCount < 10) this._curSuffix = "_m";
         // else if (this._largeRetryCount < 10) this._curSuffix = "_l";
         if (field instanceof ImageField) paths = [[this.choosePath(field.url), nativeWidth / nativeHeight]];
         paths.push(...altpaths);
         // }
-        let dragging = !SelectionManager.GetIsDragging() ? "" : "-dragging";
-        let rotation = NumCast(this.Document.rotation, 0);
-        let aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
-        let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
-        let srcpath = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][0] as string;
-        let srcaspect = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][1] as number;
-        let fadepath = paths[Math.min(paths.length - 1, 1)][0] as string;
+        const dragging = !SelectionManager.GetIsDragging() ? "" : "-dragging";
+        const rotation = NumCast(this.Document.rotation, 0);
+        const aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
+        const shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
+        const srcpath = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][0] as string;
+        const srcaspect = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][1] as number;
+        const fadepath = paths[Math.min(paths.length - 1, 1)][0] as string;
 
         !this.Document.ignoreAspect && this.resize(srcpath);
 
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index aa6e135fe..fba29e4cd 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -53,13 +53,13 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         }
     }
     public static CompileKVPScript(value: string): KVPScript | undefined {
-        let eq = value.startsWith("=");
+        const eq = value.startsWith("=");
         value = eq ? value.substr(1) : value;
         const dubEq = value.startsWith(":=") ? "computed" : value.startsWith(";=") ? "script" : false;
         value = dubEq ? value.substr(2) : value;
-        let options: ScriptOptions = { addReturn: true, params: { this: "Doc" } };
+        const options: ScriptOptions = { addReturn: true, params: { this: "Doc" } };
         if (dubEq) options.typecheck = false;
-        let script = CompileScript(value, options);
+        const script = CompileScript(value, options);
         if (!script.compiled) {
             return undefined;
         }
@@ -76,7 +76,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         } else if (type === "script") {
             field = new ScriptField(script);
         } else {
-            let res = script.run({ this: target }, console.log);
+            const res = script.run({ this: target }, console.log);
             if (!res.success) return false;
             field = res.result;
         }
@@ -106,14 +106,14 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     rowHeight = () => 30;
 
     createTable = () => {
-        let doc = this.fieldDocToLayout;
+        const doc = this.fieldDocToLayout;
         if (!doc) {
             return <tr><td>Loading...</td></tr>;
         }
-        let realDoc = doc;
+        const realDoc = doc;
 
-        let ids: { [key: string]: string } = {};
-        let protos = Doc.GetAllPrototypes(doc);
+        const ids: { [key: string]: string } = {};
+        const protos = Doc.GetAllPrototypes(doc);
         for (const proto of protos) {
             Object.keys(proto).forEach(key => {
                 if (!(key in ids) && realDoc[key] !== ComputedField.undefined) {
@@ -122,10 +122,10 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
             });
         }
 
-        let rows: JSX.Element[] = [];
+        const rows: JSX.Element[] = [];
         let i = 0;
         const self = this;
-        for (let key of Object.keys(ids).slice().sort()) {
+        for (const key of Object.keys(ids).slice().sort()) {
             rows.push(<KeyValuePair doc={realDoc} addDocTab={this.props.addDocTab} PanelWidth={this.props.PanelWidth} PanelHeight={this.rowHeight}
                 ref={(function () {
                     let oldEl: KeyValuePair | undefined;
@@ -163,7 +163,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
 
     @action
     onDividerMove = (e: PointerEvent): void => {
-        let nativeWidth = this._mainCont.current!.getBoundingClientRect();
+        const nativeWidth = this._mainCont.current!.getBoundingClientRect();
         this.props.Document.schemaSplitPercentage = Math.max(0, 100 - Math.round((e.clientX - nativeWidth.left) / nativeWidth.width * 100));
     }
     @action
@@ -179,10 +179,10 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     }
 
     getTemplate = async () => {
-        let parent = Docs.Create.StackingDocument([], { width: 800, height: 800, title: "Template" });
+        const parent = Docs.Create.StackingDocument([], { width: 800, height: 800, title: "Template" });
         parent.singleColumn = false;
         parent.columnWidth = 100;
-        for (let row of this.rows.filter(row => row.isChecked)) {
+        for (const row of this.rows.filter(row => row.isChecked)) {
             await this.createTemplateField(parent, row);
             row.uncheck();
         }
@@ -190,17 +190,17 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     }
 
     createTemplateField = async (parentStackingDoc: Doc, row: KeyValuePair) => {
-        let metaKey = row.props.keyName;
-        let sourceDoc = await Cast(this.props.Document.data, Doc);
+        const metaKey = row.props.keyName;
+        const sourceDoc = await Cast(this.props.Document.data, Doc);
         if (!sourceDoc) {
             return;
         }
 
-        let fieldTemplate = await this.inferType(sourceDoc[metaKey], metaKey);
+        const fieldTemplate = await this.inferType(sourceDoc[metaKey], metaKey);
         if (!fieldTemplate) {
             return;
         }
-        let previousViewType = fieldTemplate.viewType;
+        const previousViewType = fieldTemplate.viewType;
         Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(parentStackingDoc));
         previousViewType && (fieldTemplate.viewType = previousViewType);
 
@@ -208,14 +208,14 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     }
 
     inferType = async (data: FieldResult, metaKey: string) => {
-        let options = { width: 300, height: 300, title: metaKey };
+        const options = { width: 300, height: 300, title: metaKey };
         if (data instanceof RichTextField || typeof data === "string" || typeof data === "number") {
             return Docs.Create.TextDocument(options);
         } else if (data instanceof List) {
             if (data.length === 0) {
                 return Docs.Create.StackingDocument([], options);
             }
-            let first = await Cast(data[0], Doc);
+            const first = await Cast(data[0], Doc);
             if (!first || !first.data) {
                 return Docs.Create.StackingDocument([], options);
             }
@@ -235,7 +235,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     }
 
     render() {
-        let dividerDragger = this.splitPercentage === 0 ? (null) :
+        const dividerDragger = this.splitPercentage === 0 ? (null) :
             <div className="keyValueBox-dividerDragger" style={{ transform: `translate(calc(${100 - this.splitPercentage}% - 5px), 0px)` }}>
                 <div className="keyValueBox-dividerDraggerThumb" onPointerDown={this.onDividerDown} />
             </div>;
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 225565964..bca68cdd9 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -53,7 +53,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
     }
 
     render() {
-        let props: FieldViewProps = {
+        const props: FieldViewProps = {
             Document: this.props.doc,
             DataDoc: this.props.doc,
             ContainingCollectionView: undefined,
@@ -73,7 +73,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
             pinToPres: returnZero,
             ContentScaling: returnOne
         };
-        let contents = <FieldView {...props} />;
+        const contents = <FieldView {...props} />;
         // let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")";
         let protoCount = 0;
         let doc: Doc | undefined = props.Document;
@@ -85,9 +85,9 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
             doc = doc.proto;
         }
         const parenCount = Math.max(0, protoCount - 1);
-        let keyStyle = protoCount === 0 ? "black" : "blue";
+        const keyStyle = protoCount === 0 ? "black" : "blue";
 
-        let hover = { transition: "0.3s ease opacity", opacity: this.isPointerOver || this.isChecked ? 1 : 0 };
+        const hover = { transition: "0.3s ease opacity", opacity: this.isPointerOver || this.isChecked ? 1 : 0 };
 
         return (
             <tr className={this.props.rowStyle} onPointerEnter={action(() => this.isPointerOver = true)} onPointerLeave={action(() => this.isPointerOver = false)}>
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 87be1f4e9..0f5cc0fa9 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -95,7 +95,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     @undoBatch
     @action
     private applyFilter = () => {
-        let scriptText = this._scriptValue ? this._scriptValue :
+        const scriptText = this._scriptValue ? this._scriptValue :
             this._keyValue && this._valueValue ? `this.${this._keyValue} === ${this._valueValue}` : "true";
         this.props.Document.filterScript = ScriptField.MakeFunction(scriptText);
     }
@@ -116,7 +116,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => this._searchString = e.currentTarget.value;
 
     settingsPanel() {
-        let pageBtns = <>
+        const pageBtns = <>
             <button className="pdfBox-overlayButton-iconCont" key="back" title="Page Back"
                 onPointerDown={e => e.stopPropagation()} onClick={e => this.backPage()} style={{ left: 45, top: 5 }}>
                 <FontAwesomeIcon style={{ color: "white" }} icon={"arrow-left"} size="sm" />
@@ -186,7 +186,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
 
     specificContextMenu = (e: React.MouseEvent): void => {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
-        let funcs: ContextMenuProps[] = [];
+        const funcs: ContextMenuProps[] = [];
         pdfUrl && funcs.push({ description: "Copy path", event: () => Utils.CopyText(pdfUrl.url.pathname), icon: "expand-arrows-alt" });
         funcs.push({ description: "Toggle Fit Width " + (this.Document.fitWidth ? "Off" : "On"), event: () => this.Document.fitWidth = !this.Document.fitWidth, icon: "expand-arrows-alt" });
 
@@ -195,7 +195,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
 
     @computed get contentScaling() { return this.props.ContentScaling(); }
     @computed get renderTitleBox() {
-        let classname = "pdfBox" + (this.active() ? "-interactive" : "");
+        const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} style={{
             width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.contentScaling}%`,
             height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.contentScaling}%`,
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index cbb83b511..1e6894f37 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -42,7 +42,7 @@ export class PresBox extends React.Component<FieldViewProps> {
             if (value) {
                 value.forEach((item, i) => {
                     if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
-                        let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
+                        const pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
                         Doc.GetProto(pinDoc).presentationTargetDoc = item;
                         Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
                         value.splice(i, 1, pinDoc);
@@ -61,9 +61,9 @@ export class PresBox extends React.Component<FieldViewProps> {
     next = async () => {
         const current = NumCast(this.props.Document.selectedDoc);
         //asking to get document at current index
-        let docAtCurrentNext = await this.getDocAtIndex(current + 1);
+        const docAtCurrentNext = await this.getDocAtIndex(current + 1);
         if (docAtCurrentNext !== undefined) {
-            let presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
+            const presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
             let nextSelected = current + 1;
 
             for (; nextSelected < presDocs.length - 1; nextSelected++) {
@@ -78,15 +78,15 @@ export class PresBox extends React.Component<FieldViewProps> {
     back = async () => {
         const current = NumCast(this.props.Document.selectedDoc);
         //requesting for the doc at current index
-        let docAtCurrent = await this.getDocAtIndex(current);
+        const docAtCurrent = await this.getDocAtIndex(current);
         if (docAtCurrent !== undefined) {
 
             //asking for its presentation id.
             let prevSelected = current;
             let zoomOut: boolean = false;
 
-            let presDocs = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
-            let currentsArray: Doc[] = [];
+            const presDocs = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
+            const currentsArray: Doc[] = [];
             for (; presDocs && prevSelected > 0 && presDocs[prevSelected].groupButton; prevSelected--) {
                 currentsArray.push(presDocs[prevSelected]);
             }
@@ -104,8 +104,8 @@ export class PresBox extends React.Component<FieldViewProps> {
             //If so making sure to zoom out, which goes back to state before zooming action
             if (current > 0) {
                 if (zoomOut || docAtCurrent.showButton) {
-                    let prevScale = NumCast(this.childDocs[prevSelected].viewScale, null);
-                    let curScale = DocumentManager.Instance.getScaleOfDocView(this.childDocs[current]);
+                    const prevScale = NumCast(this.childDocs[prevSelected].viewScale, null);
+                    const curScale = DocumentManager.Instance.getScaleOfDocView(this.childDocs[current]);
                     if (prevScale !== undefined && prevScale !== curScale) {
                         DocumentManager.Instance.zoomIntoScale(docAtCurrent, prevScale);
                     }
@@ -162,13 +162,13 @@ export class PresBox extends React.Component<FieldViewProps> {
      * te option open, navigates to that element.
      */
     navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
-        let fromDoc = this.childDocs[fromDocIndex].presentationTargetDoc as Doc;
+        const fromDoc = this.childDocs[fromDocIndex].presentationTargetDoc as Doc;
         let docToJump = curDoc;
         let willZoom = false;
 
-        let presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
+        const presDocs = DocListCast(this.props.Document[this.props.fieldKey]);
         let nextSelected = presDocs.indexOf(curDoc);
-        let currentDocGroups: Doc[] = [];
+        const currentDocGroups: Doc[] = [];
         for (; nextSelected < presDocs.length - 1; nextSelected++) {
             if (!presDocs[nextSelected + 1].groupButton) {
                 break;
@@ -190,11 +190,11 @@ export class PresBox extends React.Component<FieldViewProps> {
         //docToJump stayed same meaning, it was not in the group or was the last element in the group
         if (docToJump === curDoc) {
             //checking if curDoc has navigation open
-            let target = await curDoc.presentationTargetDoc as Doc;
+            const target = await curDoc.presentationTargetDoc as Doc;
             if (curDoc.navButton) {
                 DocumentManager.Instance.jumpToDocument(target, false);
             } else if (curDoc.showButton) {
-                let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
+                const curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
                 //awaiting jump so that new scale can be found, since jumping is async
                 await DocumentManager.Instance.jumpToDocument(target, true);
                 curDoc.viewScale = DocumentManager.Instance.getScaleOfDocView(target);
@@ -207,11 +207,11 @@ export class PresBox extends React.Component<FieldViewProps> {
             }
             return;
         }
-        let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
+        const curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
 
         //awaiting jump so that new scale can be found, since jumping is async
         await DocumentManager.Instance.jumpToDocument(await docToJump.presentationTargetDoc as Doc, willZoom);
-        let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.presentationTargetDoc as Doc);
+        const newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.presentationTargetDoc as Doc);
         curDoc.viewScale = newScale;
         //saving the scale that user was on
         if (curScale !== 1) {
@@ -238,7 +238,7 @@ export class PresBox extends React.Component<FieldViewProps> {
     public removeDocument = (doc: Doc) => {
         const value = FieldValue(Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)));
         if (value) {
-            let indexOfDoc = value.indexOf(doc);
+            const indexOfDoc = value.indexOf(doc);
             if (indexOfDoc !== - 1) {
                 value.splice(indexOfDoc, 1)[0];
                 return true;
@@ -337,13 +337,13 @@ export class PresBox extends React.Component<FieldViewProps> {
     @action
     initializeScaleViews = (docList: Doc[], viewtype: number) => {
         this.props.Document.chromeStatus = "disabled";
-        let hgt = (viewtype === CollectionViewType.Tree) ? 50 : 72;
+        const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 72;
         docList.forEach((doc: Doc) => {
             doc.presBox = this.props.Document;
             doc.presBoxKey = this.props.fieldKey;
             doc.collapsedHeight = hgt;
             doc.height = ComputedField.MakeFunction("this.collapsedHeight + Number(this.embedOpen ? 100:0)");
-            let curScale = NumCast(doc.viewScale, null);
+            const curScale = NumCast(doc.viewScale, null);
             if (curScale === undefined) {
                 doc.viewScale = 1;
             }
@@ -352,7 +352,7 @@ export class PresBox extends React.Component<FieldViewProps> {
 
 
     selectElement = (doc: Doc) => {
-        let index = DocListCast(this.props.Document[this.props.fieldKey]).indexOf(doc);
+        const index = DocListCast(this.props.Document[this.props.fieldKey]).indexOf(doc);
         index !== -1 && this.gotoDocument(index, NumCast(this.props.Document.selectedDoc));
     }
 
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 741dcada0..376d27380 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -22,7 +22,7 @@ import { InkingControl } from "../InkingControl";
 import { FieldView, FieldViewProps } from './FieldView';
 import "./VideoBox.scss";
 import { documentSchema, positionSchema } from "../../../new_fields/documentSchemas";
-var path = require('path');
+const path = require('path');
 
 export const timeSchema = createSchema({
     currentTimecode: "number",  // the current time of a video or other linear, time-based document.  Note, should really get set on an extension field, but that's more complicated when it needs to be set since the extension doc needs to be found first
@@ -54,9 +54,9 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     }
 
     videoLoad = () => {
-        let aspect = this.player!.videoWidth / this.player!.videoHeight;
-        var nativeWidth = (this.Document.nativeWidth || 0);
-        var nativeHeight = (this.Document.nativeHeight || 0);
+        const aspect = this.player!.videoWidth / this.player!.videoHeight;
+        const nativeWidth = (this.Document.nativeWidth || 0);
+        const nativeHeight = (this.Document.nativeHeight || 0);
         if (!nativeWidth || !nativeHeight) {
             if (!this.Document.nativeWidth) this.Document.nativeWidth = this.player!.videoWidth;
             this.Document.nativeHeight = (this.Document.nativeWidth || 0) / aspect;
@@ -101,12 +101,12 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     }
 
     @action public Snapshot() {
-        let width = this.Document.width || 0;
-        let height = this.Document.height || 0;
-        var canvas = document.createElement('canvas');
+        const width = this.Document.width || 0;
+        const height = this.Document.height || 0;
+        const canvas = document.createElement('canvas');
         canvas.width = 640;
         canvas.height = 640 * (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1);
-        var ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
+        const ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
         if (ctx) {
             ctx.rect(0, 0, canvas.width, canvas.height);
             ctx.fillStyle = "blue";
@@ -115,20 +115,20 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         }
 
         if (!this._videoRef) { // can't find a way to take snapshots of videos
-            let b = Docs.Create.ButtonDocument({
+            const b = Docs.Create.ButtonDocument({
                 x: (this.Document.x || 0) + width, y: (this.Document.y || 0),
                 width: 150, height: 50, title: (this.Document.currentTimecode || 0).toString()
             });
             b.onClick = ScriptField.MakeScript(`this.currentTimecode = ${(this.Document.currentTimecode || 0)}`);
         } else {
             //convert to desired file format
-            var dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
+            const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
             // if you want to preview the captured image,
-            let filename = path.basename(encodeURIComponent("snapshot" + StrCast(this.Document.title).replace(/\..*$/, "") + "_" + (this.Document.currentTimecode || 0).toString().replace(/\./, "_")));
+            const filename = path.basename(encodeURIComponent("snapshot" + StrCast(this.Document.title).replace(/\..*$/, "") + "_" + (this.Document.currentTimecode || 0).toString().replace(/\./, "_")));
             VideoBox.convertDataUri(dataUrl, filename).then(returnedFilename => {
                 if (returnedFilename) {
-                    let url = this.choosePath(Utils.prepend(returnedFilename));
-                    let imageSummary = Docs.Create.ImageDocument(url, {
+                    const url = this.choosePath(Utils.prepend(returnedFilename));
+                    const imageSummary = Docs.Create.ImageDocument(url, {
                         x: (this.Document.x || 0) + width, y: (this.Document.y || 0),
                         width: 150, height: height / width * 150, title: "--snapshot" + (this.Document.currentTimecode || 0) + " image-"
                     });
@@ -150,9 +150,9 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         if (this.props.setVideoBox) this.props.setVideoBox(this);
 
         if (this.youtubeVideoId) {
-            let youtubeaspect = 400 / 315;
-            var nativeWidth = (this.Document.nativeWidth || 0);
-            var nativeHeight = (this.Document.nativeHeight || 0);
+            const youtubeaspect = 400 / 315;
+            const nativeWidth = (this.Document.nativeWidth || 0);
+            const nativeHeight = (this.Document.nativeHeight || 0);
             if (!nativeWidth || !nativeHeight) {
                 if (!this.Document.nativeWidth) this.Document.nativeWidth = 600;
                 this.Document.nativeHeight = (this.Document.nativeWidth || 0) / youtubeaspect;
@@ -181,7 +181,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
 
     public static async convertDataUri(imageUri: string, returnedFilename: string) {
         try {
-            let posting = Utils.prepend("/uploadURI");
+            const posting = Utils.prepend("/uploadURI");
             const returnedUri = await rp.post(posting, {
                 body: {
                     uri: imageUri,
@@ -196,10 +196,10 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         }
     }
     specificContextMenu = (e: React.MouseEvent): void => {
-        let field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
+        const field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
         if (field) {
-            let url = field.url.href;
-            let subitems: ContextMenuProps[] = [];
+            const url = field.url.href;
+            const subitems: ContextMenuProps[] = [];
             subitems.push({ description: "Copy path", event: () => { Utils.CopyText(url); }, icon: "expand-arrows-alt" });
             subitems.push({ description: "Toggle Show Controls", event: action(() => VideoBox._showControls = !VideoBox._showControls), icon: "expand-arrows-alt" });
             subitems.push({ description: "Take Snapshot", event: () => this.Snapshot(), icon: "expand-arrows-alt" });
@@ -208,9 +208,9 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     }
 
     @computed get content() {
-        let field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
-        let interactive = InkingControl.Instance.selectedTool || !this.props.isSelected() ? "" : "-interactive";
-        let style = "videoBox-content" + (this._fullScreen ? "-fullScreen" : "") + interactive;
+        const field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
+        const interactive = InkingControl.Instance.selectedTool || !this.props.isSelected() ? "" : "-interactive";
+        const style = "videoBox-content" + (this._fullScreen ? "-fullScreen" : "") + interactive;
         return !field ? <div>Loading</div> :
             <video className={`${style}`} key="video" ref={this.setVideoRef} onCanPlay={this.videoLoad} controls={VideoBox._showControls}
                 onPlay={() => this.Play()} onSeeked={this.updateTimecode} onPause={() => this.Pause()} onClick={e => e.preventDefault()}>
@@ -220,7 +220,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     }
 
     @computed get youtubeVideoId() {
-        let field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
+        const field = Cast(this.dataDoc[this.props.fieldKey], VideoField);
         return field && field.url.href.indexOf("youtube") !== -1 ? ((arr: string[]) => arr[arr.length - 1])(field.url.href.split("/")) : "";
     }
 
@@ -231,9 +231,9 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         }
         else this._youtubeContentCreated = false;
 
-        let iframe = e.target;
+        const iframe = e.target;
         let started = true;
-        let onYoutubePlayerStateChange = (event: any) => runInAction(() => {
+        const onYoutubePlayerStateChange = (event: any) => runInAction(() => {
             if (started && event.data === YT.PlayerState.PLAYING) {
                 started = false;
                 this._youtubePlayer && this._youtubePlayer.unMute();
@@ -243,12 +243,12 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
             if (event.data === YT.PlayerState.PLAYING && !this._playing) this.Play(false);
             if (event.data === YT.PlayerState.PAUSED && this._playing) this.Pause(false);
         });
-        let onYoutubePlayerReady = (event: any) => {
+        const onYoutubePlayerReady = (event: any) => {
             this._reactionDisposer && this._reactionDisposer();
             this._youtubeReactionDisposer && this._youtubeReactionDisposer();
             this._reactionDisposer = reaction(() => this.Document.currentTimecode, () => !this._playing && this.Seek(this.Document.currentTimecode || 0));
             this._youtubeReactionDisposer = reaction(() => [this.props.isSelected(), DocumentDecorations.Instance.Interacting, InkingControl.Instance.selectedTool], () => {
-                let interactive = InkingControl.Instance.selectedTool === InkTool.None && this.props.isSelected(true) && !DocumentDecorations.Instance.Interacting;
+                const interactive = InkingControl.Instance.selectedTool === InkTool.None && this.props.isSelected(true) && !DocumentDecorations.Instance.Interacting;
                 iframe.style.pointerEvents = interactive ? "all" : "none";
             }, { fireImmediately: true });
         };
@@ -261,8 +261,8 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
 
     }
     private get uIButtons() {
-        let scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale);
-        let curTime = (this.Document.currentTimecode || 0);
+        const scaling = Math.min(1.8, this.props.ScreenToLocalTransform().Scale);
+        const curTime = (this.Document.currentTimecode || 0);
         return ([<div className="videoBox-time" key="time" onPointerDown={this.onResetDown} >
             <span>{"" + Math.round(curTime)}</span>
             <span style={{ fontSize: 8 }}>{" " + Math.round((curTime - Math.trunc(curTime)) * 100)}</span>
@@ -318,8 +318,8 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     @computed get youtubeContent() {
         this._youtubeIframeId = VideoBox._youtubeIframeCounter++;
         this._youtubeContentCreated = this._forceCreateYouTubeIFrame ? true : true;
-        let style = "videoBox-content-YouTube" + (this._fullScreen ? "-fullScreen" : "");
-        let start = untracked(() => Math.round(this.Document.currentTimecode || 0));
+        const style = "videoBox-content-YouTube" + (this._fullScreen ? "-fullScreen" : "");
+        const start = untracked(() => Math.round(this.Document.currentTimecode || 0));
         return <iframe key={this._youtubeIframeId} id={`${this.youtubeVideoId + this._youtubeIframeId}-player`}
             onLoad={this.youtubeIframeLoaded} className={`${style}`} width={(this.Document.nativeWidth || 640)} height={(this.Document.nativeHeight || 390)}
             src={`https://www.youtube.com/embed/${this.youtubeVideoId}?enablejsapi=1&rel=0&showinfo=1&autoplay=1&mute=1&start=${start}&modestbranding=1&controls=${VideoBox._showControls ? 1 : 0}`} />;
@@ -327,7 +327,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
 
     @action.bound
     addDocumentWithTimestamp(doc: Doc): boolean {
-        var curTime = (this.Document.currentTimecode || -1);
+        const curTime = (this.Document.currentTimecode || -1);
         curTime !== -1 && (doc.displayTimecode = curTime);
         return this.addDocument(doc);
     }
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 5af743859..b0a93224d 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -36,11 +36,11 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
 
     componentWillMount() {
 
-        let field = Cast(this.props.Document[this.props.fieldKey], WebField);
+        const field = Cast(this.props.Document[this.props.fieldKey], WebField);
         if (field && field.url.href.indexOf("youtube") !== -1) {
-            let youtubeaspect = 400 / 315;
-            var nativeWidth = NumCast(this.layoutDoc.nativeWidth);
-            var nativeHeight = NumCast(this.layoutDoc.nativeHeight);
+            const youtubeaspect = 400 / 315;
+            const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
+            const nativeHeight = NumCast(this.layoutDoc.nativeHeight);
             if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
                 if (!nativeWidth) this.layoutDoc.nativeWidth = 600;
                 this.layoutDoc.nativeHeight = NumCast(this.layoutDoc.nativeWidth) / youtubeaspect;
@@ -65,7 +65,7 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
 
     @action
     setURL() {
-        let urlField: FieldResult<WebField> = Cast(this.props.Document.data, WebField);
+        const urlField: FieldResult<WebField> = Cast(this.props.Document.data, WebField);
         if (urlField) this.url = urlField.url.toString();
         else this.url = "";
     }
@@ -80,10 +80,10 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
 
     switchToText = () => {
         let url: string = "";
-        let field = Cast(this.props.Document[this.props.fieldKey], WebField);
+        const field = Cast(this.props.Document[this.props.fieldKey], WebField);
         if (field) url = field.url.href;
 
-        let newBox = Docs.Create.TextDocument({
+        const newBox = Docs.Create.TextDocument({
             x: NumCast(this.props.Document.x),
             y: NumCast(this.props.Document.y),
             title: url,
@@ -167,7 +167,7 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
 
     @computed
     get content() {
-        let field = this.dataDoc[this.props.fieldKey];
+        const field = this.dataDoc[this.props.fieldKey];
         let view;
         if (field instanceof HtmlField) {
             view = <span id="webBox-htmlSpan" dangerouslySetInnerHTML={{ __html: field.html }} />;
@@ -176,15 +176,15 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
         } else {
             view = <iframe src={"https://crossorigin.me/https://cs.brown.edu"} style={{ position: "absolute", width: "100%", height: "100%", top: 0 }} />;
         }
-        let content =
+        const content =
             <div style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
                 {this.urlEditor()}
                 {view}
             </div>;
 
-        let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
+        const frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
 
-        let classname = "webBox-cont" + (this.props.isSelected() && InkingControl.Instance.selectedTool === InkTool.None && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
+        const classname = "webBox-cont" + (this.props.isSelected() && InkingControl.Instance.selectedTool === InkTool.None && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
         return (
             <>
                 <div className={classname}  >
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 936af9ab8..6599c0e3c 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -62,11 +62,11 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
     }
 
     deleteAnnotation = () => {
-        let annotation = DocListCast(this.props.extensionDoc.annotations);
-        let group = FieldValue(Cast(this.props.document.group, Doc));
+        const annotation = DocListCast(this.props.extensionDoc.annotations);
+        const group = FieldValue(Cast(this.props.document.group, Doc));
         if (group) {
             if (annotation.indexOf(group) !== -1) {
-                let newAnnotations = annotation.filter(a => a !== FieldValue(Cast(this.props.document.group, Doc)));
+                const newAnnotations = annotation.filter(a => a !== FieldValue(Cast(this.props.document.group, Doc)));
                 this.props.extensionDoc.annotations = new List<Doc>(newAnnotations);
             }
 
@@ -77,7 +77,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
     }
 
     pinToPres = () => {
-        let group = FieldValue(Cast(this.props.document.group, Doc));
+        const group = FieldValue(Cast(this.props.document.group, Doc));
         group && this.props.pinToPres(group);
     }
 
@@ -93,7 +93,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
             e.stopPropagation();
         }
         else if (e.button === 0) {
-            let annoGroup = await Cast(this.props.document.group, Doc);
+            const annoGroup = await Cast(this.props.document.group, Doc);
             if (annoGroup) {
                 DocumentManager.Instance.FollowLink(undefined, annoGroup,
                     (doc: Doc, maxLocation: string) => this.props.addDocTab(doc, undefined, e.ctrlKey ? "inTab" : "onRight"),
@@ -105,9 +105,9 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
 
 
     addTag = (key: string, value: string): boolean => {
-        let group = FieldValue(Cast(this.props.document.group, Doc));
+        const group = FieldValue(Cast(this.props.document.group, Doc));
         if (group) {
-            let valNum = parseInt(value);
+            const valNum = parseInt(value);
             group[key] = isNaN(valNum) ? value : valNum;
             return true;
         }
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index c64741769..38e10e99a 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -128,7 +128,7 @@ export default class PDFMenu extends AntimodeMenu {
     }
 
     render() {
-        let buttons = this.Status === "pdf" || this.Status === "snippet" ?
+        const buttons = this.Status === "pdf" || this.Status === "snippet" ?
             [
                 <button key="1" className="antimodeMenu-button" title="Click to Highlight" onClick={this.highlightClicked} style={this.Highlighting ? { backgroundColor: "#121212" } : {}}>
                     <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: "transform 0.1s", transform: this.Highlighting ? "" : "rotate(-45deg)" }} /></button>,
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index c075a4f99..69aacc902 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -169,7 +169,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
 
     copy = (e: ClipboardEvent) => {
         if (this.props.active(true) && e.clipboardData) {
-            let annoDoc = this.makeAnnotationDocument("rgba(3,144,152,0.3)");  // copied text markup color (blueish)
+            const annoDoc = this.makeAnnotationDocument("rgba(3,144,152,0.3)");  // copied text markup color (blueish)
             if (annoDoc) {
                 e.clipboardData.setData("text/plain", this._selectionText);
                 e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]);
@@ -212,7 +212,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         this._filterReactionDisposer = reaction(
             () => ({ scriptField: Cast(this.Document.filterScript, ScriptField), annos: this._annotations.slice() }),
             action(({ scriptField, annos }: { scriptField: FieldResult<ScriptField>, annos: Doc[] }) => {
-                let oldScript = this._script.originalScript;
+                const oldScript = this._script.originalScript;
                 this._script = scriptField && scriptField.script.compiled ? scriptField.script : CompileScript("return true") as CompiledScript;
                 if (this._script.originalScript !== oldScript) {
                     this.Index = -1;
@@ -240,8 +240,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             this.gotoPage(this.Document.curPage || 1);
         }));
         document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
-        var pdfLinkService = new PDFJSViewer.PDFLinkService();
-        let pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService });
+        const pdfLinkService = new PDFJSViewer.PDFLinkService();
+        const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService });
         this._pdfViewer = new PDFJSViewer.PDFViewer({
             container: this._mainCont.current,
             viewer: this._viewer.current,
@@ -260,12 +260,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         if (this._savedAnnotations.size() === 0) return undefined;
         let mainAnnoDoc = Docs.Create.InstanceFromProto(new Doc(), "", {});
         let mainAnnoDocProto = Doc.GetProto(mainAnnoDoc);
-        let annoDocs: Doc[] = [];
+        const annoDocs: Doc[] = [];
         let maxX = -Number.MAX_VALUE;
         let minY = Number.MAX_VALUE;
         if ((this._savedAnnotations.values()[0][0] as any).marqueeing) {
-            let anno = this._savedAnnotations.values()[0][0];
-            let annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, title: "Annotation on " + this.Document.title });
+            const anno = this._savedAnnotations.values()[0][0];
+            const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, title: "Annotation on " + this.Document.title });
             if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
             if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
             if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
@@ -280,7 +280,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             mainAnnoDocProto.y = annoDoc.y;
         } else {
             this._savedAnnotations.forEach((key: number, value: HTMLDivElement[]) => value.map(anno => {
-                let annoDoc = new Doc();
+                const annoDoc = new Doc();
                 if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
                 if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
                 if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
@@ -324,7 +324,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     @action
     scrollToAnnotation = (scrollToAnnotation: Doc) => {
         if (scrollToAnnotation) {
-            let offset = this.visibleHeight() / 2 * 96 / 72;
+            const offset = this.visibleHeight() / 2 * 96 / 72;
             this._mainCont.current && smoothScroll(500, this._mainCont.current, NumCast(scrollToAnnotation.y) - offset);
             Doc.linkFollowHighlight(scrollToAnnotation);
         }
@@ -356,7 +356,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             this._annotationLayer.current.append(div);
             div.style.backgroundColor = "yellow";
             div.style.opacity = "0.5";
-            let savedPage = this._savedAnnotations.getValue(page);
+            const savedPage = this._savedAnnotations.getValue(page);
             if (savedPage) {
                 savedPage.push(div);
                 this._savedAnnotations.setValue(page, savedPage);
@@ -382,7 +382,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             });
         }
         else if (this._mainCont.current) {
-            let executeFind = () => {
+            const executeFind = () => {
                 this._pdfViewer.findController.executeCommand('find', {
                     caseSensitive: false,
                     findPrevious: !fwd,
@@ -398,7 +398,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
 
     @action
     onPointerDown = (e: React.PointerEvent): void => {
-        let hit = document.elementFromPoint(e.clientX, e.clientY);
+        const hit = document.elementFromPoint(e.clientX, e.clientY);
         if (hit && hit.localName === "span" && this.props.isSelected(true)) {  // drag selecting text stops propagation
             e.button === 0 && e.stopPropagation();
         }
@@ -425,7 +425,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             }
             else if (this._mainCont.current) {
                 // set marquee x and y positions to the spatially transformed position
-                let boundingRect = this._mainCont.current.getBoundingClientRect();
+                const boundingRect = this._mainCont.current.getBoundingClientRect();
                 this._startX = this._marqueeX = (e.clientX - boundingRect.left) * (this._mainCont.current.offsetWidth / boundingRect.width);
                 this._startY = this._marqueeY = (e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height) + this._mainCont.current.scrollTop;
                 this._marqueeHeight = this._marqueeWidth = 0;
@@ -442,7 +442,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     onSelectMove = (e: PointerEvent): void => {
         if (this._marqueeing && this._mainCont.current) {
             // transform positions and find the width and height to set the marquee to
-            let boundingRect = this._mainCont.current.getBoundingClientRect();
+            const boundingRect = this._mainCont.current.getBoundingClientRect();
             this._marqueeWidth = ((e.clientX - boundingRect.left) * (this._mainCont.current.offsetWidth / boundingRect.width)) - this._startX;
             this._marqueeHeight = ((e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height)) - this._startY + this._mainCont.current.scrollTop;
             this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth);
@@ -460,16 +460,16 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     @action
     createTextAnnotation = (sel: Selection, selRange: Range) => {
         if (this._mainCont.current) {
-            let boundingRect = this._mainCont.current.getBoundingClientRect();
-            let clientRects = selRange.getClientRects();
+            const boundingRect = this._mainCont.current.getBoundingClientRect();
+            const clientRects = selRange.getClientRects();
             for (let i = 0; i < clientRects.length; i++) {
-                let rect = clientRects.item(i);
+                const rect = clientRects.item(i);
                 if (rect) {
-                    let scaleY = this._mainCont.current.offsetHeight / boundingRect.height;
-                    let scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
+                    const scaleY = this._mainCont.current.offsetHeight / boundingRect.height;
+                    const scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
                     if (rect.width !== this._mainCont.current.clientWidth &&
                         (i === 0 || !intersectRect(clientRects[i], clientRects[i - 1]))) {
-                        let annoBox = document.createElement("div");
+                        const annoBox = document.createElement("div");
                         annoBox.className = "pdfViewer-annotationBox";
                         // transforms the positions from screen onto the pdf div
                         annoBox.style.top = ((rect.top - boundingRect.top) * scaleY / this._zoomed + this._mainCont.current.scrollTop).toString();
@@ -497,10 +497,10 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         this._savedAnnotations.clear();
         if (this._marqueeing) {
             if (this._marqueeWidth > 10 || this._marqueeHeight > 10) {
-                let marquees = this._mainCont.current!.getElementsByClassName("pdfViewer-dragAnnotationBox");
+                const marquees = this._mainCont.current!.getElementsByClassName("pdfViewer-dragAnnotationBox");
                 if (marquees && marquees.length) { // copy the marquee and convert it to a permanent annotation. 
-                    let style = (marquees[0] as HTMLDivElement).style;
-                    let copy = document.createElement("div");
+                    const style = (marquees[0] as HTMLDivElement).style;
+                    const copy = document.createElement("div");
                     copy.style.left = style.left;
                     copy.style.top = style.top;
                     copy.style.width = style.width;
@@ -521,9 +521,9 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             this._marqueeing = false;
         }
         else {
-            let sel = window.getSelection();
+            const sel = window.getSelection();
             if (sel && sel.type === "Range") {
-                let selRange = sel.getRangeAt(0);
+                const selRange = sel.getRangeAt(0);
                 this.createTextAnnotation(sel, selRange);
                 PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
             }
@@ -543,7 +543,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     @action
     highlight = (color: string) => {
         // creates annotation documents for current highlights
-        let annotationDoc = this.makeAnnotationDocument(color);
+        const annotationDoc = this.makeAnnotationDocument(color);
         annotationDoc && this.props.addDocument && this.props.addDocument(annotationDoc);
         return annotationDoc;
     }
@@ -556,10 +556,10 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     startDrag = (e: PointerEvent, ele: HTMLElement): void => {
         e.preventDefault();
         e.stopPropagation();
-        let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
+        const targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
         const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
         if (annotationDoc) {
-            let dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
+            const dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
             DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
                 handlers: {
                     dragComplete: () => !(dragData as any).linkedToDoc &&
@@ -572,8 +572,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     }
 
     createSnippet = (marquee: { left: number, top: number, width: number, height: number }): void => {
-        let view = Doc.MakeAlias(this.props.Document);
-        let data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
+        const view = Doc.MakeAlias(this.props.Document);
+        const data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
         data.title = StrCast(data.title) + "_snippet";
         view.proto = data;
         view.nativeHeight = marquee.height;
@@ -605,8 +605,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 this.Document.nativeHeight = nativeWidth * this._coverPath.height / this._coverPath.width;
             }).bind(this), 0);
         }
-        let nativeWidth = (this.Document.nativeWidth || 0);
-        let nativeHeight = (this.Document.nativeHeight || 0);
+        const nativeWidth = (this.Document.nativeWidth || 0);
+        const nativeHeight = (this.Document.nativeHeight || 0);
         return <img key={this._coverPath.path} src={this._coverPath.path} onError={action(() => this._coverPath.path = "http://www.cs.brown.edu/~bcz/face.gif")} onLoad={action(() => this._showWaiting = false)}
             style={{ position: "absolute", display: "inline-block", top: 0, left: 0, width: `${nativeWidth}px`, height: `${nativeHeight}px` }} />;
     }
@@ -615,7 +615,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     onZoomWheel = (e: React.WheelEvent) => {
         e.stopPropagation();
         if (e.ctrlKey) {
-            let curScale = Number(this._pdfViewer.currentScaleValue);
+            const curScale = Number(this._pdfViewer.currentScaleValue);
             this._pdfViewer.currentScaleValue = Math.max(1, Math.min(10, curScale - curScale * e.deltaY / 1000));
             this._zoomed = Number(this._pdfViewer.currentScaleValue);
         }
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index f50a3a0ef..47f876ac2 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -161,9 +161,9 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
             return (null);
         }
 
-        let propDocWidth = NumCast(this.layoutDoc.nativeWidth);
-        let propDocHeight = NumCast(this.layoutDoc.nativeHeight);
-        let scale = () => 175 / NumCast(this.layoutDoc.nativeWidth, 175);
+        const propDocWidth = NumCast(this.layoutDoc.nativeWidth);
+        const propDocHeight = NumCast(this.layoutDoc.nativeHeight);
+        const scale = () => 175 / NumCast(this.layoutDoc.nativeWidth, 175);
         return (
             <div className="presElementBox-embedded" style={{
                 height: propDocHeight === 0 ? NumCast(this.layoutDoc.height) - NumCast(this.layoutDoc.collapsedHeight) : propDocHeight * scale(),
@@ -193,9 +193,9 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
     }
 
     render() {
-        let treecontainer = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.viewType === CollectionViewType.Tree;
-        let className = "presElementBox-item" + (this.currentIndex === this.indexInPres ? " presElementBox-selected" : "");
-        let pbi = "presElementBox-interaction";
+        const treecontainer = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.viewType === CollectionViewType.Tree;
+        const className = "presElementBox-item" + (this.currentIndex === this.indexInPres ? " presElementBox-selected" : "");
+        const pbi = "presElementBox-interaction";
         return (
             <div className={className} key={this.props.Document[Id] + this.indexInPres}
                 style={{ outlineWidth: Doc.IsBrushed(this.targetDoc) ? `1px` : "0px", }}
diff --git a/src/client/views/search/FilterBox.tsx b/src/client/views/search/FilterBox.tsx
index 7812c9d97..12e1bc265 100644
--- a/src/client/views/search/FilterBox.tsx
+++ b/src/client/views/search/FilterBox.tsx
@@ -79,7 +79,7 @@ export class FilterBox extends React.Component {
                 acc[i].addEventListener("click", function (this: HTMLElement) {
                     this.classList.toggle("active");
 
-                    var panel = this.nextElementSibling as HTMLElement;
+                    const panel = this.nextElementSibling as HTMLElement;
                     if (panel.style.maxHeight) {
                         panel.style.overflow = "hidden";
                         panel.style.maxHeight = "";
@@ -96,7 +96,7 @@ export class FilterBox extends React.Component {
                     }
                 });
 
-                let el = acc[i] as HTMLElement;
+                const el = acc[i] as HTMLElement;
                 el.click();
             }
         });
@@ -105,14 +105,14 @@ export class FilterBox extends React.Component {
     @action.bound
     minimizeAll() {
         $('document').ready(function () {
-            var acc = document.getElementsByClassName('filter-header');
+            const acc = document.getElementsByClassName('filter-header');
 
             // tslint:disable-next-line: prefer-for-of
             for (var i = 0; i < acc.length; i++) {
-                let classList = acc[i].classList;
+                const classList = acc[i].classList;
                 if (classList.contains("active")) {
                     acc[i].classList.toggle("active");
-                    var panel = acc[i].nextElementSibling as HTMLElement;
+                    const panel = acc[i].nextElementSibling as HTMLElement;
                     panel.style.overflow = "hidden";
                     panel.style.maxHeight = "";
                 }
@@ -128,10 +128,10 @@ export class FilterBox extends React.Component {
     }
 
     basicRequireWords(query: string): string {
-        let oldWords = query.split(" ");
-        let newWords: string[] = [];
+        const oldWords = query.split(" ");
+        const newWords: string[] = [];
         oldWords.forEach(word => {
-            let newWrd = "+" + word;
+            const newWrd = "+" + word;
             newWords.push(newWrd);
         });
         query = newWords.join(" ");
@@ -140,7 +140,7 @@ export class FilterBox extends React.Component {
     }
 
     basicFieldFilters(query: string, type: string): string {
-        let oldWords = query.split(" ");
+        const oldWords = query.split(" ");
         let mod = "";
 
         if (type === Keys.AUTHOR) {
@@ -151,9 +151,9 @@ export class FilterBox extends React.Component {
             mod = " title_t:";
         }
 
-        let newWords: string[] = [];
+        const newWords: string[] = [];
         oldWords.forEach(word => {
-            let newWrd = mod + word;
+            const newWrd = mod + word;
             newWords.push(newWrd);
         });
 
@@ -183,11 +183,11 @@ export class FilterBox extends React.Component {
     //gets all of the collections of all the docviews that are selected
     //if a collection is the only thing selected, search only in that collection (not its container)
     getCurCollections(): Doc[] {
-        let selectedDocs: DocumentView[] = SelectionManager.SelectedDocuments();
-        let collections: Doc[] = [];
+        const selectedDocs: DocumentView[] = SelectionManager.SelectedDocuments();
+        const collections: Doc[] = [];
 
         selectedDocs.forEach(async element => {
-            let layout: string = StrCast(element.props.Document.layout);
+            const layout: string = StrCast(element.props.Document.layout);
             //checks if selected view (element) is a collection. if it is, adds to list to search through
             if (layout.indexOf("Collection") > -1) {
                 //makes sure collections aren't added more than once
@@ -229,14 +229,14 @@ export class FilterBox extends React.Component {
     }
 
     addCollectionFilter(query: string): string {
-        let collections: Doc[] = this.getCurCollections();
-        let oldWords = query.split(" ");
+        const collections: Doc[] = this.getCurCollections();
+        const oldWords = query.split(" ");
 
-        let collectionString: string[] = [];
+        const collectionString: string[] = [];
         collections.forEach(doc => {
-            let proto = doc.proto;
-            let protoId = (proto || doc)[Id];
-            let colString: string = "{!join from=data_l to=id}id:" + protoId + " ";
+            const proto = doc.proto;
+            const protoId = (proto || doc)[Id];
+            const colString: string = "{!join from=data_l to=id}id:" + protoId + " ";
             collectionString.push(colString);
         });
 
@@ -254,9 +254,9 @@ export class FilterBox extends React.Component {
         if (this._icons.length === 9) {
             return docs;
         }
-        let finalDocs: Doc[] = [];
+        const finalDocs: Doc[] = [];
         docs.forEach(doc => {
-            let layoutresult = Cast(doc.type, "string");
+            const layoutresult = Cast(doc.type, "string");
             if (layoutresult && this._icons.includes(layoutresult)) {
                 finalDocs.push(doc);
             }
diff --git a/src/client/views/search/IconButton.tsx b/src/client/views/search/IconButton.tsx
index d2cfe7fad..f01508141 100644
--- a/src/client/views/search/IconButton.tsx
+++ b/src/client/views/search/IconButton.tsx
@@ -108,7 +108,7 @@ export class IconButton extends React.Component<IconButtonProps>{
 
     @action.bound
     onClick = () => {
-        let newList: string[] = FilterBox.Instance.getIcons();
+        const newList: string[] = FilterBox.Instance.getIcons();
 
         if (!this._isSelected) {
             this._isSelected = true;
diff --git a/src/client/views/search/NaviconButton.tsx b/src/client/views/search/NaviconButton.tsx
index 3fa36b163..0fa4a0fca 100644
--- a/src/client/views/search/NaviconButton.tsx
+++ b/src/client/views/search/NaviconButton.tsx
@@ -4,7 +4,7 @@ import "./NaviconButton.scss";
 import * as $ from 'jquery';
 import { observable } from 'mobx';
 
-export interface NaviconProps{
+export interface NaviconProps {
     onClick(): void;
 }
 
@@ -13,19 +13,21 @@ export class NaviconButton extends React.Component<NaviconProps> {
     @observable private _ref: React.RefObject<HTMLAnchorElement> = React.createRef();
 
     componentDidMount = () => {
-        let that = this;
-        if(this._ref.current){this._ref.current.addEventListener("click", function(e) {
-            e.preventDefault();
-            if(that._ref.current){
-                that._ref.current.classList.toggle('active');
-                return false;
-            }
-        });}
+        const that = this;
+        if (this._ref.current) {
+            this._ref.current.addEventListener("click", function (e) {
+                e.preventDefault();
+                if (that._ref.current) {
+                    that._ref.current.classList.toggle('active');
+                    return false;
+                }
+            });
+        }
     }
 
     render() {
         return (
-            <a id="hamburger-icon" href="#" ref = {this._ref} title="Menu">
+            <a id="hamburger-icon" href="#" ref={this._ref} title="Menu">
                 <span className="line line-1"></span>
                 <span className="line line-2"></span>
                 <span className="line line-3"></span>
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index ff35542ed..c45fbe210 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -89,7 +89,7 @@ export class SearchBox extends React.Component {
 
     public static async convertDataUri(imageUri: string, returnedFilename: string) {
         try {
-            let posting = Utils.prepend("/uploadURI");
+            const posting = Utils.prepend("/uploadURI");
             const returnedUri = await rp.post(posting, {
                 body: {
                     uri: imageUri,
@@ -166,7 +166,7 @@ export class SearchBox extends React.Component {
                     const docs = await Promise.all(res.docs.map(async doc => (await Cast(doc.extendsDoc, Doc)) || doc));
                     const highlights: typeof res.highlighting = {};
                     docs.forEach((doc, index) => highlights[doc[Id]] = highlightList[index]);
-                    let filteredDocs = FilterBox.Instance.filterDocsByType(docs);
+                    const filteredDocs = FilterBox.Instance.filterDocsByType(docs);
                     runInAction(() => {
                         // this._results.push(...filteredDocs);
                         filteredDocs.forEach(doc => {
@@ -198,8 +198,8 @@ export class SearchBox extends React.Component {
 
     collectionRef = React.createRef<HTMLSpanElement>();
     startDragCollection = async () => {
-        let res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString));
-        let filtered = FilterBox.Instance.filterDocsByType(res.docs);
+        const res = await this.getAllResults(FilterBox.Instance.getFinalQuery(this._searchString));
+        const filtered = FilterBox.Instance.filterDocsByType(res.docs);
         // console.log(this._results)
         const docs = filtered.map(doc => {
             const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
@@ -266,10 +266,10 @@ export class SearchBox extends React.Component {
 
     @action
     resultsScrolled = (e?: React.UIEvent<HTMLDivElement>) => {
-        let scrollY = e ? e.currentTarget.scrollTop : this.resultsRef.current ? this.resultsRef.current.scrollTop : 0;
-        let itemHght = 53;
-        let startIndex = Math.floor(Math.max(0, scrollY / itemHght));
-        let endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this.resultsRef.current!.getBoundingClientRect().height / itemHght)));
+        const scrollY = e ? e.currentTarget.scrollTop : this.resultsRef.current ? this.resultsRef.current.scrollTop : 0;
+        const itemHght = 53;
+        const startIndex = Math.floor(Math.max(0, scrollY / itemHght));
+        const endIndex = Math.ceil(Math.min(this._numTotalResults - 1, startIndex + (this.resultsRef.current!.getBoundingClientRect().height / itemHght)));
 
         this._endIndex = endIndex === -1 ? 12 : endIndex;
 
@@ -307,7 +307,7 @@ export class SearchBox extends React.Component {
                         this.getResults(this._searchString);
                         if (i < this._results.length) result = this._results[i];
                         if (result) {
-                            let highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
+                            const highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
                             this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />;
                             this._isSearch[i] = "search";
                         }
@@ -315,7 +315,7 @@ export class SearchBox extends React.Component {
                     else {
                         result = this._results[i];
                         if (result) {
-                            let highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
+                            const highlights = Array.from([...Array.from(new Set(result[1]).values())]).filter(v => v !== "search_string");
                             this._visibleElements[i] = <SearchItem doc={result[0]} query={this._searchString} key={result[0][Id]} lines={result[2]} highlighting={highlights} />;
                             this._isSearch[i] = "search";
                         }
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index f1d825aa0..6ffff0562 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -52,7 +52,7 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> {
     }
 
     async fetchDocuments() {
-        let aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc);
+        const aliases = (await SearchUtil.GetViewsOfDocument(this.props.doc)).filter(doc => doc !== this.props.doc);
         const { docs } = await SearchUtil.Search("", true, { fq: `data_l:"${this.props.doc[Id]}"` });
         const map: Map<Doc, Doc> = new Map;
         const allDocs = await Promise.all(aliases.map(doc => SearchUtil.Search("", true, { fq: `data_l:"${doc[Id]}"` }).then(result => result.docs)));
@@ -82,7 +82,7 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> {
             <div className="parents">
                 <p className="contexts">Contexts:</p>
                 {[...this._docs, ...this._otherDocs].map(doc => {
-                    let item = React.createRef<HTMLDivElement>();
+                    const item = React.createRef<HTMLDivElement>();
                     return <div className="collection" key={doc.col[Id] + doc.target[Id]} ref={item}>
                         <div className="collection-item" onPointerDown={
                             SetupDrag(item, () => doc.col, undefined, undefined, undefined, undefined, () => SearchBox.Instance.closeSearch())}>
@@ -146,11 +146,11 @@ export class SearchItem extends React.Component<SearchItemProps> {
     //@computed
     @action
     public DocumentIcon() {
-        let layoutresult = StrCast(this.props.doc.type);
+        const layoutresult = StrCast(this.props.doc.type);
         if (!this._useIcons) {
-            let returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
-            let returnYDimension = () => this._displayDim;
-            let scale = () => returnXDimension() / NumCast(Doc.Layout(this.props.doc).nativeWidth, returnXDimension());
+            const returnXDimension = () => this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE);
+            const returnYDimension = () => this._displayDim;
+            const scale = () => returnXDimension() / NumCast(Doc.Layout(this.props.doc).nativeWidth, returnXDimension());
             const docview = <div
                 onPointerDown={action(() => {
                     this._useIcons = !this._useIcons;
@@ -184,7 +184,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
             </div>;
             return docview;
         }
-        let button = layoutresult.indexOf(DocumentType.PDF) !== -1 ? faFilePdf :
+        const button = layoutresult.indexOf(DocumentType.PDF) !== -1 ? faFilePdf :
             layoutresult.indexOf(DocumentType.IMG) !== -1 ? faImage :
                 layoutresult.indexOf(DocumentType.TEXT) !== -1 ? faStickyNote :
                     layoutresult.indexOf(DocumentType.VID) !== -1 ? faFilm :
@@ -201,7 +201,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
 
     collectionRef = React.createRef<HTMLDivElement>();
     startDocDrag = () => {
-        let doc = this.props.doc;
+        const doc = this.props.doc;
         const isProto = Doc.GetT(doc, "isPrototype", "boolean", true);
         if (isProto) {
             return Doc.MakeDelegate(doc);
@@ -218,7 +218,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
 
     nextHighlight = (e: React.PointerEvent) => {
         e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e);
-        let sstring = StrCast(this.props.doc.search_string);
+        const sstring = StrCast(this.props.doc.search_string);
         this.props.doc.search_string = "";
         setTimeout(() => this.props.doc.search_string = sstring, 0);
     }
@@ -226,8 +226,8 @@ export class SearchItem extends React.Component<SearchItemProps> {
         if (this.props.doc.type === DocumentType.LINK) {
             if (this.props.doc.anchor1 && this.props.doc.anchor2) {
 
-                let doc1 = Cast(this.props.doc.anchor1, Doc, null);
-                let doc2 = Cast(this.props.doc.anchor2, Doc, null);
+                const doc1 = Cast(this.props.doc.anchor1, Doc, null);
+                const doc2 = Cast(this.props.doc.anchor2, Doc, null);
                 Doc.BrushDoc(doc1);
                 Doc.BrushDoc(doc2);
             }
@@ -241,8 +241,8 @@ export class SearchItem extends React.Component<SearchItemProps> {
         if (this.props.doc.type === DocumentType.LINK) {
             if (this.props.doc.anchor1 && this.props.doc.anchor2) {
 
-                let doc1 = Cast(this.props.doc.anchor1, Doc, null);
-                let doc2 = Cast(this.props.doc.anchor2, Doc, null);
+                const doc1 = Cast(this.props.doc.anchor1, Doc, null);
+                const doc2 = Cast(this.props.doc.anchor2, Doc, null);
                 Doc.UnBrushDoc(doc1);
                 Doc.UnBrushDoc(doc2);
             }
diff --git a/src/client/views/search/ToggleBar.tsx b/src/client/views/search/ToggleBar.tsx
index ed5ecd3ba..e4d7f2fd5 100644
--- a/src/client/views/search/ToggleBar.tsx
+++ b/src/client/views/search/ToggleBar.tsx
@@ -33,8 +33,7 @@ export class ToggleBar extends React.Component<ToggleBarProps>{
     }
 
     componentDidMount = () => {
-
-        let totalWidth = 265;
+        const totalWidth = 265;
 
         if (this._originalStatus) {
             this._forwardTimeline.add({
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index 24db3f934..a26d2e06a 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -24,7 +24,7 @@ CursorField;
 function applyToDoc(doc: { [index: string]: FieldResult }, key: string, scriptString: string): boolean;
 function applyToDoc(doc: { [index: number]: FieldResult }, key: number, scriptString: string): boolean;
 function applyToDoc(doc: any, key: string | number, scriptString: string): boolean {
-    let script = CompileScript(scriptString, { addReturn: true, params: { this: doc instanceof Doc ? Doc.name : List.name } });
+    const script = CompileScript(scriptString, { addReturn: true, params: { this: doc instanceof Doc ? Doc.name : List.name } });
     if (!script.compiled) {
         return false;
     }
@@ -85,7 +85,7 @@ class DocumentViewer extends React.Component<{ field: Doc }> {
         let content;
         if (this.expanded) {
             const keys = Object.keys(this.props.field);
-            let fields = keys.map(key => {
+            const fields = keys.map(key => {
                 return (
                     <div key={key}>
                         <b>({key}): </b>
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 9fdaac66e..ec698b151 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -34,13 +34,13 @@ class Uploader extends React.Component {
         try {
             this.status = "initializing protos";
             await Docs.Prototypes.initialize();
-            let imgPrev = document.getElementById("img_preview");
+            const imgPrev = document.getElementById("img_preview");
             if (imgPrev) {
-                let files: FileList | null = inputRef.current!.files;
+                const files: FileList | null = inputRef.current!.files;
                 if (files && files.length !== 0) {
                     console.log(files[0]);
                     const name = files[0].name;
-                    let formData = new FormData();
+                    const formData = new FormData();
                     formData.append("file", files[0]);
 
                     const upload = window.location.origin + "/upload";
@@ -52,8 +52,8 @@ class Uploader extends React.Component {
                     this.status = "upload image, getting json";
                     const json = await res.json();
                     json.map(async (file: any) => {
-                        let path = window.location.origin + file;
-                        var doc = Docs.Create.ImageDocument(path, { nativeWidth: 200, width: 200, title: name });
+                        const path = window.location.origin + file;
+                        const doc = Docs.Create.ImageDocument(path, { nativeWidth: 200, width: 200, title: name });
 
                         this.status = "getting user document";
 
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index a811322d7..cf32fa74a 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -21,7 +21,7 @@ export namespace Field {
     export function toKeyValueString(doc: Doc, key: string): string {
         const onDelegate = Object.keys(doc).includes(key);
 
-        let field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+        const field = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
         if (Field.IsField(field)) {
             return (onDelegate ? "=" : "") + (field instanceof ComputedField ? `:=${field.script.originalScript}` : Field.toScriptString(field));
         }
@@ -255,9 +255,9 @@ export namespace Doc {
         return GetT(doc, "isPrototype", "boolean", true);
     }
     export async function SetInPlace(doc: Doc, key: string, value: Field | undefined, defaultProto: boolean) {
-        let hasProto = doc.proto instanceof Doc;
-        let onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
-        let onProto = hasProto && Object.getOwnPropertyNames(doc.proto).indexOf(key) !== -1;
+        const hasProto = doc.proto instanceof Doc;
+        const onDeleg = Object.getOwnPropertyNames(doc).indexOf(key) !== -1;
+        const onProto = hasProto && Object.getOwnPropertyNames(doc.proto).indexOf(key) !== -1;
         if (onDeleg || !hasProto || (!onProto && !defaultProto)) {
             doc[key] = value;
         } else doc.proto![key] = value;
@@ -306,10 +306,10 @@ export namespace Doc {
     // compare whether documents or their protos match
     export function AreProtosEqual(doc?: Doc, other?: Doc) {
         if (!doc || !other) return false;
-        let r = (doc === other);
-        let r2 = (Doc.GetProto(doc) === other);
-        let r3 = (Doc.GetProto(other) === doc);
-        let r4 = (Doc.GetProto(doc) === Doc.GetProto(other) && Doc.GetProto(other) !== undefined);
+        const r = (doc === other);
+        const r2 = (Doc.GetProto(doc) === other);
+        const r3 = (Doc.GetProto(other) === doc);
+        const r4 = (Doc.GetProto(doc) === Doc.GetProto(other) && Doc.GetProto(other) !== undefined);
         return r || r2 || r3 || r4;
     }
 
@@ -318,7 +318,7 @@ export namespace Doc {
         return doc && (Doc.GetT(doc, "isPrototype", "boolean", true) ? doc : (doc.proto || doc));
     }
     export function GetDataDoc(doc: Doc): Doc {
-        let proto = Doc.GetProto(doc);
+        const proto = Doc.GetProto(doc);
         return proto === doc ? proto : Doc.GetDataDoc(proto);
     }
 
@@ -343,9 +343,9 @@ export namespace Doc {
         if (listDoc[key] === undefined) {
             Doc.GetProto(listDoc)[key] = new List<Doc>();
         }
-        let list = Cast(listDoc[key], listSpec(Doc));
+        const list = Cast(listDoc[key], listSpec(Doc));
         if (list) {
-            let ind = list.indexOf(doc);
+            const ind = list.indexOf(doc);
             if (ind !== -1) {
                 list.splice(ind, 1);
                 return true;
@@ -357,10 +357,10 @@ export namespace Doc {
         if (listDoc[key] === undefined) {
             Doc.GetProto(listDoc)[key] = new List<Doc>();
         }
-        let list = Cast(listDoc[key], listSpec(Doc));
+        const list = Cast(listDoc[key], listSpec(Doc));
         if (list) {
             if (allowDuplicates !== true) {
-                let pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1);
+                const pind = list.reduce((l, d, i) => d instanceof Doc && d[Id] === doc[Id] ? i : l, -1);
                 if (pind !== -1) {
                     list.splice(pind, 1);
                 }
@@ -369,7 +369,7 @@ export namespace Doc {
                 list.splice(0, 0, doc);
             }
             else {
-                let ind = relativeTo ? list.indexOf(relativeTo) : -1;
+                const ind = relativeTo ? list.indexOf(relativeTo) : -1;
                 if (ind === -1) {
                     if (reversed) list.splice(0, 0, doc);
                     else list.push(doc);
@@ -388,9 +388,9 @@ export namespace Doc {
     // Computes the bounds of the contents of a set of documents.
     //
     export function ComputeContentBounds(docList: Doc[]) {
-        let bounds = docList.reduce((bounds, doc) => {
-            var [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)];
-            let [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()];
+        const bounds = docList.reduce((bounds, doc) => {
+            const [sptX, sptY] = [NumCast(doc.x), NumCast(doc.y)];
+            const [bptX, bptY] = [sptX + doc[WidthSym](), sptY + doc[HeightSym]()];
             return {
                 x: Math.min(sptX, bounds.x), y: Math.min(sptY, bounds.y),
                 r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
@@ -400,16 +400,16 @@ export namespace Doc {
     }
 
     export function MakeTitled(title: string) {
-        let doc = new Doc();
+        const doc = new Doc();
         doc.title = title;
         return doc;
     }
     export function MakeAlias(doc: Doc) {
-        let alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc);
+        const alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc);
         if (alias.layout instanceof Doc) {
             alias.layout = Doc.MakeAlias(alias.layout);
         }
-        let aliasNumber = Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1;
+        const aliasNumber = Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1;
         alias.title = ComputedField.MakeFunction(`renameAlias(this, ${aliasNumber})`);
         return alias;
     }
@@ -437,8 +437,8 @@ export namespace Doc {
         // ... which means we change the layout to be an expanded view of the template layout.  
         // This allows the view override the template's properties and be referenceable as its own document.
 
-        let expandedLayoutFieldKey = "Layout[" + templateLayoutDoc[Id] + "]";
-        let expandedTemplateLayout = dataDoc[expandedLayoutFieldKey];
+        const expandedLayoutFieldKey = "Layout[" + templateLayoutDoc[Id] + "]";
+        const expandedTemplateLayout = dataDoc[expandedLayoutFieldKey];
         if (expandedTemplateLayout instanceof Doc) {
             return expandedTemplateLayout;
         }
@@ -451,9 +451,9 @@ export namespace Doc {
 
     export function GetLayoutDataDocPair(doc: Doc, dataDoc: Doc | undefined, fieldKey: string, childDocLayout: Doc) {
         let layoutDoc: Doc | undefined = childDocLayout;
-        let resolvedDataDoc = !doc.isTemplateField && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined;
+        const resolvedDataDoc = !doc.isTemplateField && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined;
         if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
-            let extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
+            const extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
             layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined);
         } else layoutDoc = childDocLayout;
         return { layout: layoutDoc, data: resolvedDataDoc };
@@ -467,13 +467,13 @@ export namespace Doc {
     // to store annotations, ink, and other data.
     //
     export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
-        let extension = doc[fieldKey + "_ext"] as Doc;
+        const extension = doc[fieldKey + "_ext"] as Doc;
         (extension === undefined) && setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
         return extension ? extension : undefined;
     }
 
     export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
-        let docExtensionForField = new Doc(doc[Id] + fieldKey, true);
+        const docExtensionForField = new Doc(doc[Id] + fieldKey, true);
         docExtensionForField.title = fieldKey + ".ext"; // courtesy field--- shouldn't be needed except maybe for debugging
         docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends.
         docExtensionForField.extendsField = fieldKey; // this can be used by search to map matches on the extension doc back to the field that was extended.
@@ -512,7 +512,7 @@ export namespace Doc {
     export function MakeCopy(doc: Doc, copyProto: boolean = false, copyProtoId?: string): Doc {
         const copy = new Doc(copyProtoId, true);
         Object.keys(doc).forEach(key => {
-            let cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
+            const cfield = ComputedField.WithoutComputed(() => FieldValue(doc[key]));
             const field = ProxyField.WithoutProxy(() => doc[key]);
             if (key === "proto" && copyProto) {
                 if (doc[key] instanceof Doc) {
@@ -551,7 +551,7 @@ export namespace Doc {
     let _applyCount: number = 0;
     export function ApplyTemplate(templateDoc: Doc) {
         if (templateDoc) {
-            let applied = ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), "layoutCustom", templateDoc.title + "(..." + _applyCount++ + ")");
+            const applied = ApplyTemplateTo(templateDoc, Doc.MakeDelegate(new Doc()), "layoutCustom", templateDoc.title + "(..." + _applyCount++ + ")");
             applied && (Doc.GetProto(applied).layout = applied.layout);
             return applied;
         }
@@ -567,7 +567,7 @@ export namespace Doc {
             return;
         }
 
-        let layoutCustomLayout = Doc.MakeDelegate(templateDoc);
+        const layoutCustomLayout = Doc.MakeDelegate(templateDoc);
 
         titleTarget && (Doc.GetProto(target).title = titleTarget);
         Doc.GetProto(target).type = DocumentType.TEMPLATE;
@@ -580,7 +580,7 @@ export namespace Doc {
 
     export function MakeMetadataFieldTemplate(fieldTemplate: Doc, templateDataDoc: Doc, suppressTitle: boolean = false): boolean {
         // move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??)
-        let metadataFieldName = StrCast(fieldTemplate.title).replace(/^-/, "");
+        const metadataFieldName = StrCast(fieldTemplate.title).replace(/^-/, "");
         let fieldLayoutDoc = fieldTemplate;
         if (fieldTemplate.layout instanceof Doc) {
             fieldLayoutDoc = Doc.MakeDelegate(fieldTemplate.layout);
@@ -601,11 +601,11 @@ export namespace Doc {
         fieldTemplate.panY = 0;
         fieldTemplate.scale = 1;
         fieldTemplate.showTitle = suppressTitle ? undefined : "title";
-        let data = fieldTemplate.data;
+        const data = fieldTemplate.data;
         // setTimeout(action(() => {
         !templateDataDoc[metadataFieldName] && data instanceof ObjectField && (Doc.GetProto(templateDataDoc)[metadataFieldName] = ObjectField.MakeCopy(data));
-        let layout = StrCast(fieldLayoutDoc.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metadataFieldName}"}`);
-        let layoutDelegate = Doc.Layout(fieldTemplate);
+        const layout = StrCast(fieldLayoutDoc.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metadataFieldName}"}`);
+        const layoutDelegate = Doc.Layout(fieldTemplate);
         layoutDelegate.layout = layout;
         fieldTemplate.layout = layoutDelegate !== fieldTemplate ? layoutDelegate : layout;
         if (fieldTemplate.backgroundColor !== templateDataDoc.defaultBackgroundColor) fieldTemplate.defaultBackgroundColor = fieldTemplate.backgroundColor;
@@ -615,16 +615,16 @@ export namespace Doc {
     }
 
     export function overlapping(doc1: Doc, doc2: Doc, clusterDistance: number) {
-        let doc2Layout = Doc.Layout(doc2);
-        let doc1Layout = Doc.Layout(doc1);
-        var x2 = NumCast(doc2.x) - clusterDistance;
-        var y2 = NumCast(doc2.y) - clusterDistance;
-        var w2 = NumCast(doc2Layout.width) + clusterDistance;
-        var h2 = NumCast(doc2Layout.height) + clusterDistance;
-        var x = NumCast(doc1.x) - clusterDistance;
-        var y = NumCast(doc1.y) - clusterDistance;
-        var w = NumCast(doc1Layout.width) + clusterDistance;
-        var h = NumCast(doc1Layout.height) + clusterDistance;
+        const doc2Layout = Doc.Layout(doc2);
+        const doc1Layout = Doc.Layout(doc1);
+        const x2 = NumCast(doc2.x) - clusterDistance;
+        const y2 = NumCast(doc2.y) - clusterDistance;
+        const w2 = NumCast(doc2Layout.width) + clusterDistance;
+        const h2 = NumCast(doc2Layout.height) + clusterDistance;
+        const x = NumCast(doc1.x) - clusterDistance;
+        const y = NumCast(doc1.y) - clusterDistance;
+        const w = NumCast(doc1Layout.width) + clusterDistance;
+        const h = NumCast(doc1Layout.height) + clusterDistance;
         return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
     }
 
@@ -691,7 +691,7 @@ export namespace Doc {
         Doc.HighlightDoc(destDoc);
         document.removeEventListener("pointerdown", linkFollowUnhighlight);
         document.addEventListener("pointerdown", linkFollowUnhighlight);
-        let x = dt = Date.now();
+        const x = dt = Date.now();
         window.setTimeout(() => dt === x && linkFollowUnhighlight(), 5000);
     }
 
@@ -700,7 +700,7 @@ export namespace Doc {
     }
     const highlightManager = new HighlightBrush();
     export function IsHighlighted(doc: Doc) {
-        let IsHighlighted = highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetDataDoc(doc));
+        const IsHighlighted = highlightManager.HighlightedDoc.get(doc) || highlightManager.HighlightedDoc.get(Doc.GetDataDoc(doc));
         return IsHighlighted;
     }
     export function HighlightDoc(doc: Doc) {
@@ -716,10 +716,10 @@ export namespace Doc {
         });
     }
     export function UnhighlightAll() {
-        let mapEntries = highlightManager.HighlightedDoc.keys();
+        const mapEntries = highlightManager.HighlightedDoc.keys();
         let docEntry: IteratorResult<Doc>;
         while (!(docEntry = mapEntries.next()).done) {
-            let targetDoc = docEntry.value;
+            const targetDoc = docEntry.value;
             targetDoc && Doc.UnHighlightDoc(targetDoc);
         }
 
diff --git a/src/new_fields/List.ts b/src/new_fields/List.ts
index 0c7b77fa5..e9101158b 100644
--- a/src/new_fields/List.ts
+++ b/src/new_fields/List.ts
@@ -270,8 +270,8 @@ class ListImpl<T extends Field> extends ObjectField {
     }
 
     [Copy]() {
-        let copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
-        let deepCopy = new ListImpl<T>(copiedData as any);
+        const copiedData = this[Self].__fields.map(f => f instanceof ObjectField ? f[Copy]() : f);
+        const deepCopy = new ListImpl<T>(copiedData as any);
         return deepCopy;
     }
 
diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts
index dc5574782..682206aa2 100644
--- a/src/new_fields/RichTextUtils.ts
+++ b/src/new_fields/RichTextUtils.ts
@@ -25,8 +25,8 @@ export namespace RichTextUtils {
 
 
     export const Initialize = (initial?: string) => {
-        let content: any[] = [];
-        let state = {
+        const content: any[] = [];
+        const state = {
             doc: {
                 type: "doc",
                 content,
@@ -56,32 +56,32 @@ export namespace RichTextUtils {
 
     export const ToPlainText = (state: EditorState) => {
         // Because we're working with plain text, just concatenate all paragraphs
-        let content = state.doc.content;
-        let paragraphs: Node<any>[] = [];
+        const content = state.doc.content;
+        const paragraphs: Node<any>[] = [];
         content.forEach(node => node.type.name === "paragraph" && paragraphs.push(node));
 
         // Functions to flatten ProseMirror paragraph objects (and their components) to plain text
         // Concatentate paragraphs and string the result together
-        let textParagraphs: string[] = paragraphs.map(paragraph => {
-            let text: string[] = [];
+        const textParagraphs: string[] = paragraphs.map(paragraph => {
+            const text: string[] = [];
             paragraph.content.forEach(node => node.text && text.push(node.text));
             return text.join(joiner) + delimiter;
         });
-        let plainText = textParagraphs.join(joiner);
+        const plainText = textParagraphs.join(joiner);
         return plainText.substring(0, plainText.length - 1);
     };
 
     export const ToProsemirrorState = (plainText: string, oldState?: RichTextField) => {
         // Remap the text, creating blocks split on newlines
-        let elements = plainText.split(delimiter);
+        const elements = plainText.split(delimiter);
 
         // Google Docs adds in an extra carriage return automatically, so this counteracts it
         !elements[elements.length - 1].length && elements.pop();
 
         // Preserve the current state, but re-write the content to be the blocks
-        let parsed = JSON.parse(oldState ? oldState.Data : Initialize());
+        const parsed = JSON.parse(oldState ? oldState.Data : Initialize());
         parsed.doc.content = elements.map(text => {
-            let paragraph: any = { type: "paragraph" };
+            const paragraph: any = { type: "paragraph" };
             text.length && (paragraph.content = [{ type: "text", marks: [], text }]); // An empty paragraph gets treated as a line break
             return paragraph;
         });
@@ -97,7 +97,7 @@ export namespace RichTextUtils {
 
         export const Export = async (state: EditorState): Promise<GoogleApiClientUtils.Docs.Content> => {
             const nodes: (Node<any> | null)[] = [];
-            let text = ToPlainText(state);
+            const text = ToPlainText(state);
             state.doc.content.forEach(node => {
                 if (!node.childCount) {
                     nodes.push(null);
@@ -168,20 +168,20 @@ export namespace RichTextUtils {
             const title = document.title!;
             const { text, paragraphs } = GoogleApiClientUtils.Docs.Utils.extractText(document);
             let state = FormattedTextBox.blankState();
-            let structured = parseLists(paragraphs);
+            const structured = parseLists(paragraphs);
 
             let position = 3;
-            let lists: ListGroup[] = [];
+            const lists: ListGroup[] = [];
             const indentMap = new Map<ListGroup, BulletPosition[]>();
             let globalOffset = 0;
             const nodes: Node<any>[] = [];
-            for (let element of structured) {
+            for (const element of structured) {
                 if (Array.isArray(element)) {
                     lists.push(element);
-                    let positions: BulletPosition[] = [];
-                    let items = element.map(paragraph => {
-                        let item = listItem(state.schema, paragraph.contents);
-                        let sinks = paragraph.bullet!;
+                    const positions: BulletPosition[] = [];
+                    const items = element.map(paragraph => {
+                        const item = listItem(state.schema, paragraph.contents);
+                        const sinks = paragraph.bullet!;
                         positions.push({
                             value: position + globalOffset,
                             sinks
@@ -208,7 +208,7 @@ export namespace RichTextUtils {
                             }
                         });
                     } else {
-                        let paragraph = paragraphNode(state.schema, element.contents);
+                        const paragraph = paragraphNode(state.schema, element.contents);
                         nodes.push(paragraph);
                         position += paragraph.nodeSize;
                     }
@@ -216,11 +216,11 @@ export namespace RichTextUtils {
             }
             state = state.apply(state.tr.replaceWith(0, 2, nodes));
 
-            let sink = sinkListItem(state.schema.nodes.list_item);
-            let dispatcher = (tr: Transaction) => state = state.apply(tr);
-            for (let list of lists) {
-                for (let pos of indentMap.get(list)!) {
-                    let resolved = state.doc.resolve(pos.value);
+            const sink = sinkListItem(state.schema.nodes.list_item);
+            const dispatcher = (tr: Transaction) => state = state.apply(tr);
+            for (const list of lists) {
+                for (const pos of indentMap.get(list)!) {
+                    const resolved = state.doc.resolve(pos.value);
                     state = state.apply(state.tr.setSelection(new TextSelection(resolved)));
                     for (let i = 0; i < pos.sinks; i++) {
                         sink(state, dispatcher);
@@ -236,9 +236,9 @@ export namespace RichTextUtils {
         type PreparedParagraphs = (ListGroup | Paragraph)[];
 
         const parseLists = (paragraphs: ListGroup) => {
-            let groups: PreparedParagraphs = [];
+            const groups: PreparedParagraphs = [];
             let group: ListGroup = [];
-            for (let paragraph of paragraphs) {
+            for (const paragraph of paragraphs) {
                 if (paragraph.bullet !== undefined) {
                     group.push(paragraph);
                 } else {
@@ -262,8 +262,8 @@ export namespace RichTextUtils {
         };
 
         const paragraphNode = (schema: any, runs: docs_v1.Schema$TextRun[]): Node => {
-            let children = runs.map(run => textNode(schema, run)).filter(child => child !== undefined);
-            let fragment = children.length ? Fragment.from(children) : undefined;
+            const children = runs.map(run => textNode(schema, run)).filter(child => child !== undefined);
+            const fragment = children.length ? Fragment.from(children) : undefined;
             return schema.node("paragraph", null, fragment);
         };
 
@@ -284,7 +284,7 @@ export namespace RichTextUtils {
         };
 
         const textNode = (schema: any, run: docs_v1.Schema$TextRun) => {
-            let text = run.content!.removeTrailingNewlines();
+            const text = run.content!.removeTrailingNewlines();
             return text.length ? schema.text(text, styleToMarks(schema, run.textStyle)) : undefined;
         };
 
@@ -299,17 +299,17 @@ export namespace RichTextUtils {
             if (!textStyle) {
                 return undefined;
             }
-            let marks: Mark[] = [];
+            const marks: Mark[] = [];
             Object.keys(textStyle).forEach(key => {
                 let value: any;
-                let targeted = key as keyof docs_v1.Schema$TextStyle;
+                const targeted = key as keyof docs_v1.Schema$TextStyle;
                 if (value = textStyle[targeted]) {
-                    let attributes: any = {};
+                    const attributes: any = {};
                     let converted = StyleToMark.get(targeted) || targeted;
 
                     value.url && (attributes.href = value.url);
                     if (value.color) {
-                        let object = value.color.rgbColor;
+                        const object = value.color.rgbColor;
                         attributes.color = Color.rgb(["red", "green", "blue"].map(color => object[color] * 255 || 0)).hex();
                     }
                     if (value.magnitude) {
@@ -320,13 +320,13 @@ export namespace RichTextUtils {
                         converted = ImportFontFamilyMapping.get(value.fontFamily) || "timesNewRoman";
                     }
 
-                    let mapped = schema.marks[converted];
+                    const mapped = schema.marks[converted];
                     if (!mapped) {
                         alert(`No mapping found for ${converted}!`);
                         return;
                     }
 
-                    let mark = schema.mark(mapped, attributes);
+                    const mark = schema.mark(mapped, attributes);
                     mark && marks.push(mark);
                 }
             });
@@ -366,9 +366,9 @@ export namespace RichTextUtils {
         const ignored = ["user_mark"];
 
         const marksToStyle = async (nodes: (Node<any> | null)[]): Promise<docs_v1.Schema$Request[]> => {
-            let requests: docs_v1.Schema$Request[] = [];
+            const requests: docs_v1.Schema$Request[] = [];
             let position = 1;
-            for (let node of nodes) {
+            for (const node of nodes) {
                 if (node === null) {
                     position += 2;
                     continue;
@@ -382,7 +382,7 @@ export namespace RichTextUtils {
                 };
                 let mark: Mark<any>;
                 const markMap = BuildMarkMap(marks);
-                for (let markName of Object.keys(schema.marks)) {
+                for (const markName of Object.keys(schema.marks)) {
                     if (ignored.includes(markName) || !(mark = markMap[markName])) {
                         continue;
                     }
diff --git a/src/new_fields/Schema.ts b/src/new_fields/Schema.ts
index b1a449e08..3f0ff4284 100644
--- a/src/new_fields/Schema.ts
+++ b/src/new_fields/Schema.ts
@@ -23,7 +23,7 @@ export type makeInterface<T extends Interface[]> = AllToInterface<T> & Doc & { p
 // export function makeInterface<T extends Interface[], U extends Doc>(schemas: T): (doc: U) => All<T, U>;
 // export function makeInterface<T extends Interface, U extends Doc>(schema: T): (doc: U) => makeInterface<T, U>; 
 export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFunc<T> {
-    let schema: Interface = {};
+    const schema: Interface = {};
     for (const s of schemas) {
         for (const key in s) {
             schema[key] = s[key];
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
index cdc9871a8..6b2723663 100644
--- a/src/new_fields/ScriptField.ts
+++ b/src/new_fields/ScriptField.ts
@@ -102,7 +102,7 @@ export class ScriptField extends ObjectField {
         return "script field";
     }
     public static CompileScript(script: string, params: object = {}, addReturn = false) {
-        let compiled = CompileScript(script, {
+        const compiled = CompileScript(script, {
             params: { this: Doc.name, ...params },
             typecheck: false,
             editable: true,
@@ -111,12 +111,12 @@ export class ScriptField extends ObjectField {
         return compiled;
     }
     public static MakeFunction(script: string, params: object = {}) {
-        let compiled = ScriptField.CompileScript(script, params, true);
+        const compiled = ScriptField.CompileScript(script, params, true);
         return compiled.compiled ? new ScriptField(compiled) : undefined;
     }
 
     public static MakeScript(script: string, params: object = {}) {
-        let compiled = ScriptField.CompileScript(script, params, false);
+        const compiled = ScriptField.CompileScript(script, params, false);
         return compiled.compiled ? new ScriptField(compiled) : undefined;
     }
 }
@@ -127,11 +127,11 @@ export class ComputedField extends ScriptField {
     //TODO maybe add an observable cache based on what is passed in for doc, considering there shouldn't really be that many possible values for doc
     value = computedFn((doc: Doc) => this.script.run({ this: doc }, console.log).result);
     public static MakeScript(script: string, params: object = {}, ) {
-        let compiled = ScriptField.CompileScript(script, params, false);
+        const compiled = ScriptField.CompileScript(script, params, false);
         return compiled.compiled ? new ComputedField(compiled) : undefined;
     }
     public static MakeFunction(script: string, params: object = {}) {
-        let compiled = ScriptField.CompileScript(script, params, true);
+        const compiled = ScriptField.CompileScript(script, params, true);
         return compiled.compiled ? new ComputedField(compiled) : undefined;
     }
 }
diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts
index c9fc86fea..c155796a8 100644
--- a/src/server/ActionUtilities.ts
+++ b/src/server/ActionUtilities.ts
@@ -3,10 +3,11 @@ import { ExecOptions } from 'shelljs';
 import { exec } from 'child_process';
 import * as path from 'path';
 import * as rimraf from "rimraf";
+import { yellow } from 'colors';
 
 export const command_line = (command: string, fromDirectory?: string) => {
     return new Promise<string>((resolve, reject) => {
-        let options: ExecOptions = {};
+        const options: ExecOptions = {};
         if (fromDirectory) {
             options.cwd = path.join(__dirname, fromDirectory);
         }
@@ -15,14 +16,14 @@ export const command_line = (command: string, fromDirectory?: string) => {
 };
 
 export const read_text_file = (relativePath: string) => {
-    let target = path.join(__dirname, relativePath);
+    const target = path.join(__dirname, relativePath);
     return new Promise<string>((resolve, reject) => {
         fs.readFile(target, (err, data) => err ? reject(err) : resolve(data.toString()));
     });
 };
 
 export const write_text_file = (relativePath: string, contents: any) => {
-    let target = path.join(__dirname, relativePath);
+    const target = path.join(__dirname, relativePath);
     return new Promise<void>((resolve, reject) => {
         fs.writeFile(target, contents, (err) => err ? reject(err) : resolve());
     });
@@ -42,31 +43,19 @@ export async function log_execution({ startMessage, endMessage, action }: LogDat
     console.log(color, endMessage);
 }
 
-export enum ConsoleColors {
-    Black = `\x1b[30m%s\x1b[0m`,
-    Red = `\x1b[31m%s\x1b[0m`,
-    Green = `\x1b[32m%s\x1b[0m`,
-    Yellow = `\x1b[33m%s\x1b[0m`,
-    Blue = `\x1b[34m%s\x1b[0m`,
-    Magenta = `\x1b[35m%s\x1b[0m`,
-    Cyan = `\x1b[36m%s\x1b[0m`,
-    White = `\x1b[37m%s\x1b[0m`
-}
-
 export function logPort(listener: string, port: number) {
-    process.stdout.write(`${listener} listening on port `);
-    console.log(ConsoleColors.Yellow, port);
+    console.log(`${listener} listening on port ${yellow(String(port))}`);
 }
 
 export function msToTime(duration: number) {
-    let milliseconds = Math.floor((duration % 1000) / 100),
+    const milliseconds = Math.floor((duration % 1000) / 100),
         seconds = Math.floor((duration / 1000) % 60),
         minutes = Math.floor((duration / (1000 * 60)) % 60),
         hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
 
-    let hoursS = (hours < 10) ? "0" + hours : hours;
-    let minutesS = (minutes < 10) ? "0" + minutes : minutes;
-    let secondsS = (seconds < 10) ? "0" + seconds : seconds;
+    const hoursS = (hours < 10) ? "0" + hours : hours;
+    const minutesS = (minutes < 10) ? "0" + minutes : minutes;
+    const secondsS = (seconds < 10) ? "0" + seconds : seconds;
 
     return hoursS + ":" + minutesS + ":" + secondsS + "." + milliseconds;
 }
diff --git a/src/server/ApiManagers/DownloadManager.ts b/src/server/ApiManagers/DownloadManager.ts
index 5bad46eda..2280739fc 100644
--- a/src/server/ApiManagers/DownloadManager.ts
+++ b/src/server/ApiManagers/DownloadManager.ts
@@ -57,14 +57,13 @@ export default class DownloadManager extends ApiManager {
 
         register({
             method: Method.GET,
-            subscription: new RouteSubscriber("/serializeDoc").add("docId"),
+            subscription: new RouteSubscriber("serializeDoc").add("docId"),
             onValidation: async ({ req, res }) => {
                 const { docs, files } = await getDocs(req.params.docId);
                 res.send({ docs, files: Array.from(files) });
             }
         });
 
-
     }
 
 }
diff --git a/src/server/ApiManagers/GeneralGoogleManager.ts b/src/server/ApiManagers/GeneralGoogleManager.ts
index 629684e0c..3617779d5 100644
--- a/src/server/ApiManagers/GeneralGoogleManager.ts
+++ b/src/server/ApiManagers/GeneralGoogleManager.ts
@@ -38,16 +38,19 @@ export default class GeneralGoogleManager extends ApiManager {
 
         register({
             method: Method.POST,
-            subscription: new RouteSubscriber("/googleDocs").add("sector", "action"),
+            subscription: new RouteSubscriber("googleDocs").add("sector", "action"),
             onValidation: async ({ req, res, user }) => {
-                let sector: GoogleApiServerUtils.Service = req.params.sector as GoogleApiServerUtils.Service;
-                let action: GoogleApiServerUtils.Action = req.params.action as GoogleApiServerUtils.Action;
+                const sector: GoogleApiServerUtils.Service = req.params.sector as GoogleApiServerUtils.Service;
+                const action: GoogleApiServerUtils.Action = req.params.action as GoogleApiServerUtils.Action;
                 const endpoint = await GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector], user.id);
-                let handler = EndpointHandlerMap.get(action);
+                const handler = EndpointHandlerMap.get(action);
                 if (endpoint && handler) {
-                    handler(endpoint, req.body)
-                        .then(response => res.send(response.data))
-                        .catch(exception => res.send(exception));
+                    try {
+                        const response = await handler(endpoint, req.body);
+                        res.send(response.data);
+                    } catch (e) {
+                        res.send(e);
+                    }
                     return;
                 }
                 res.send(undefined);
diff --git a/src/server/ApiManagers/GooglePhotosManager.ts b/src/server/ApiManagers/GooglePhotosManager.ts
index 4a0c0b936..e2539f120 100644
--- a/src/server/ApiManagers/GooglePhotosManager.ts
+++ b/src/server/ApiManagers/GooglePhotosManager.ts
@@ -47,7 +47,7 @@ export default class GooglePhotosManager extends ApiManager {
                 if (!token) {
                     return _error(res, authenticationError);
                 }
-                let failed: GooglePhotosUploadFailure[] = [];
+                const failed: GooglePhotosUploadFailure[] = [];
                 const batched = BatchedArray.from<GooglePhotosUploadUtils.UploadSource>(media, { batchSize: 25 });
                 const newMediaItems = await batched.batchedMapPatientInterval<NewMediaItem>(
                     { magnitude: 100, unit: TimeUnit.Milliseconds },
@@ -87,7 +87,7 @@ export default class GooglePhotosManager extends ApiManager {
                 let failed = 0;
                 if (contents) {
                     const completed: Opt<DashUploadUtils.ImageUploadInformation>[] = [];
-                    for (let item of contents.mediaItems) {
+                    for (const item of contents.mediaItems) {
                         const { contentSize, ...attributes } = await DashUploadUtils.InspectImage(item.baseUrl);
                         const found: Opt<DashUploadUtils.ImageUploadInformation> = await Database.Auxiliary.QueryUploadHistory(contentSize!);
                         if (!found) {
diff --git a/src/server/ApiManagers/PDFManager.ts b/src/server/ApiManagers/PDFManager.ts
index 151b48dd9..a190ab0cb 100644
--- a/src/server/ApiManagers/PDFManager.ts
+++ b/src/server/ApiManagers/PDFManager.ts
@@ -8,7 +8,7 @@ const imageSize = require("probe-image-size");
 import * as express from "express";
 import * as path from "path";
 import { Directory, serverPathToFile, clientPathToFile } from "./UploadManager";
-import { ConsoleColors } from "../ActionUtilities";
+import { red } from "colors";
 
 export default class PDFManager extends ApiManager {
 
@@ -32,10 +32,10 @@ function getOrCreateThumbnail(thumbnailName: string, res: express.Response) {
         const path = serverPathToFile(Directory.pdf_thumbnails, thumbnailName);
         exists(path, (exists: boolean) => {
             if (exists) {
-                let existingThumbnail = createReadStream(path);
+                const existingThumbnail = createReadStream(path);
                 imageSize(existingThumbnail, (err: any, { width, height }: any) => {
                     if (err) {
-                        console.log(ConsoleColors.Red, `In PDF thumbnail response, unable to determine dimensions of ${thumbnailName}:`);
+                        console.log(red(`In PDF thumbnail response, unable to determine dimensions of ${thumbnailName}:`));
                         console.log(err);
                         return;
                     }
@@ -81,7 +81,7 @@ async function CreateThumbnail(file: string, pageNumber: number, res: express.Re
         });
     });
     out.on("error", error => {
-        console.log(ConsoleColors.Red, `In PDF thumbnail creation, encountered the following error when piping ${pngFile}:`);
+        console.log(red(`In PDF thumbnail creation, encountered the following error when piping ${pngFile}:`));
         console.log(error);
     });
 }
@@ -89,8 +89,8 @@ async function CreateThumbnail(file: string, pageNumber: number, res: express.Re
 class NodeCanvasFactory {
 
     create = (width: number, height: number) => {
-        var canvas = createCanvas(width, height);
-        var context = canvas.getContext('2d');
+        const canvas = createCanvas(width, height);
+        const context = canvas.getContext('2d');
         return {
             canvas,
             context
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index d3f8995b0..7afecbb18 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -1,7 +1,7 @@
 import ApiManager, { Registration } from "./ApiManager";
 import { Method } from "../RouteManager";
 import { Search } from "../Search";
-var findInFiles = require('find-in-files');
+const findInFiles = require('find-in-files');
 import * as path from 'path';
 import { pathToDirectory, Directory } from "./UploadManager";
 
@@ -13,14 +13,14 @@ export default class SearchManager extends ApiManager {
             method: Method.GET,
             subscription: "/textsearch",
             onValidation: async ({ req, res }) => {
-                let q = req.query.q;
+                const q = req.query.q;
                 if (q === undefined) {
                     res.send([]);
                     return;
                 }
-                let results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, pathToDirectory(Directory.text), ".txt$");
-                let resObj: { ids: string[], numFound: number, lines: string[] } = { ids: [], numFound: 0, lines: [] };
-                for (var result in results) {
+                const results = await findInFiles.find({ 'term': q, 'flags': 'ig' }, pathToDirectory(Directory.text), ".txt$");
+                const resObj: { ids: string[], numFound: number, lines: string[] } = { ids: [], numFound: 0, lines: [] };
+                for (const result in results) {
                     resObj.ids.push(path.basename(result, ".txt").replace(/upload_/, ""));
                     resObj.lines.push(results[result].line);
                     resObj.numFound++;
@@ -39,7 +39,7 @@ export default class SearchManager extends ApiManager {
                     res.send([]);
                     return;
                 }
-                let results = await Search.Instance.search(solrQuery);
+                const results = await Search.Instance.search(solrQuery);
                 res.send(results);
             }
         });
diff --git a/src/server/ApiManagers/UploadManager.ts b/src/server/ApiManagers/UploadManager.ts
index 80ae0ad61..da1f83b75 100644
--- a/src/server/ApiManagers/UploadManager.ts
+++ b/src/server/ApiManagers/UploadManager.ts
@@ -2,7 +2,7 @@ import ApiManager, { Registration } from "./ApiManager";
 import { Method, _success } from "../RouteManager";
 import * as formidable from 'formidable';
 import v4 = require('uuid/v4');
-var AdmZip = require('adm-zip');
+const AdmZip = require('adm-zip');
 import { extname, basename, dirname } from 'path';
 import { createReadStream, createWriteStream, unlink, readFileSync } from "fs";
 import { publicDirectory, filesDirectory } from "..";
@@ -42,12 +42,12 @@ export default class UploadManager extends ApiManager {
             method: Method.POST,
             subscription: "/upload",
             onValidation: async ({ req, res }) => {
-                let form = new formidable.IncomingForm();
+                const form = new formidable.IncomingForm();
                 form.uploadDir = pathToDirectory(Directory.parsed_files);
                 form.keepExtensions = true;
                 return new Promise<void>(resolve => {
                     form.parse(req, async (_err, _fields, files) => {
-                        let results: any[] = [];
+                        const results: any[] = [];
                         for (const key in files) {
                             const result = await DashUploadUtils.upload(files[key]);
                             result && results.push(result);
@@ -63,7 +63,7 @@ export default class UploadManager extends ApiManager {
             method: Method.POST,
             subscription: "/uploadDoc",
             onValidation: ({ req, res }) => {
-                let form = new formidable.IncomingForm();
+                const form = new formidable.IncomingForm();
                 form.keepExtensions = true;
                 // let path = req.body.path;
                 const ids: { [id: string]: string } = {};
@@ -122,8 +122,8 @@ export default class UploadManager extends ApiManager {
                                 zip.getEntries().forEach((entry: any) => {
                                     if (!entry.entryName.startsWith("files/")) return;
                                     let directory = dirname(entry.entryName) + "/";
-                                    let extension = extname(entry.entryName);
-                                    let base = basename(entry.entryName).split(".")[0];
+                                    const extension = extname(entry.entryName);
+                                    const base = basename(entry.entryName).split(".")[0];
                                     try {
                                         zip.extractEntryTo(entry.entryName, publicDirectory, true, false);
                                         directory = "/" + directory;
@@ -139,7 +139,7 @@ export default class UploadManager extends ApiManager {
                                 const json = zip.getEntry("doc.json");
                                 let docs: any;
                                 try {
-                                    let data = JSON.parse(json.getData().toString("utf8"));
+                                    const data = JSON.parse(json.getData().toString("utf8"));
                                     docs = data.docs;
                                     id = data.id;
                                     docs = Object.keys(docs).map(key => docs[key]);
@@ -189,7 +189,7 @@ export default class UploadManager extends ApiManager {
                 return imageDataUri.outputFile(uri, serverPathToFile(Directory.images, filename)).then((savedName: string) => {
                     const ext = extname(savedName).toLowerCase();
                     const { pngs, jpgs } = AcceptibleMedia;
-                    let resizers = [
+                    const resizers = [
                         { resizer: sharp().resize(100, undefined, { withoutEnlargement: true }), suffix: "_s" },
                         { resizer: sharp().resize(400, undefined, { withoutEnlargement: true }), suffix: "_m" },
                         { resizer: sharp().resize(900, undefined, { withoutEnlargement: true }), suffix: "_l" },
diff --git a/src/server/ApiManagers/UtilManager.ts b/src/server/ApiManagers/UtilManager.ts
index c1234be6c..601a7d0d0 100644
--- a/src/server/ApiManagers/UtilManager.ts
+++ b/src/server/ApiManagers/UtilManager.ts
@@ -35,11 +35,11 @@ export default class UtilManager extends ApiManager {
             method: Method.GET,
             subscription: "/buxton",
             onValidation: async ({ res }) => {
-                let cwd = '../scraping/buxton';
+                const cwd = '../scraping/buxton';
 
-                let onResolved = (stdout: string) => { console.log(stdout); res.redirect("/"); };
-                let onRejected = (err: any) => { console.error(err.message); res.send(err); };
-                let tryPython3 = () => command_line('python3 scraper.py', cwd).then(onResolved, onRejected);
+                const onResolved = (stdout: string) => { console.log(stdout); res.redirect("/"); };
+                const onRejected = (err: any) => { console.error(err.message); res.send(err); };
+                const tryPython3 = () => command_line('python3 scraper.py', cwd).then(onResolved, onRejected);
 
                 return command_line('python scraper.py', cwd).then(onResolved, tryPython3);
             },
diff --git a/src/server/DashUploadUtils.ts b/src/server/DashUploadUtils.ts
index 9ccc72e35..d9d985ca5 100644
--- a/src/server/DashUploadUtils.ts
+++ b/src/server/DashUploadUtils.ts
@@ -9,10 +9,11 @@ import { AcceptibleMedia } from './SharedMediaTypes';
 import { filesDirectory } from '.';
 import { File } from 'formidable';
 import { basename } from "path";
-import { ConsoleColors, createIfNotExists } from './ActionUtilities';
+import { createIfNotExists } from './ActionUtilities';
 import { ParsedPDF } from "../server/PdfTypes";
 const parse = require('pdf-parse');
 import { Directory, serverPathToFile, clientPathToFile } from './ApiManagers/UploadManager';
+import { red } from 'colors';
 
 export enum SizeSuffix {
     Small = "_s",
@@ -86,12 +87,12 @@ export namespace DashUploadUtils {
                 }
         }
 
-        console.log(ConsoleColors.Red, `Ignoring unsupported file (${name}) with upload type (${type}).`);
+        console.log(red(`Ignoring unsupported file (${name}) with upload type (${type}).`));
         return { clientAccessPath: undefined };
     }
 
     async function UploadPdf(absolutePath: string) {
-        let dataBuffer = fs.readFileSync(absolutePath);
+        const dataBuffer = fs.readFileSync(absolutePath);
         const result: ParsedPDF = await parse(dataBuffer);
         const parsedName = basename(absolutePath);
         await new Promise<void>((resolve, reject) => {
@@ -194,7 +195,7 @@ export namespace DashUploadUtils {
         const { isLocal, stream, normalizedUrl, contentSize, contentType, exifData } = metadata;
         const resolved = filename || generate(prefix, normalizedUrl);
         const extension = format || sanitizeExtension(normalizedUrl || resolved);
-        let information: ImageUploadInformation = {
+        const information: ImageUploadInformation = {
             clientAccessPath: clientPathToFile(Directory.images, resolved),
             serverAccessPaths: {},
             exifData,
@@ -215,8 +216,7 @@ export namespace DashUploadUtils {
             } else if (jpgs.includes(extension)) {
                 resizers.forEach(element => element.resizer = element.resizer.jpeg());
             }
-            for (let { resizer, suffix } of resizers) {
-                let mediaPath: string;
+            for (const { resizer, suffix } of resizers) {
                 await new Promise<void>(resolve => {
                     const filename = InjectSize(resolved, suffix);
                     information.serverAccessPaths[suffix] = serverPathToFile(Directory.images, filename);
diff --git a/src/server/Initialization.ts b/src/server/Initialization.ts
index 8b633a7cd..74770153d 100644
--- a/src/server/Initialization.ts
+++ b/src/server/Initialization.ts
@@ -19,8 +19,9 @@ import * as fs from 'fs';
 import * as request from 'request';
 import RouteSubscriber from './RouteSubscriber';
 import { publicDirectory } from '.';
-import { ConsoleColors, logPort } from './ActionUtilities';
+import { logPort } from './ActionUtilities';
 import { timeMap } from './ApiManagers/UserManager';
+import { blue, yellow } from 'colors';
 
 /* RouteSetter is a wrapper around the server that prevents the server
    from being exposed. */
@@ -53,10 +54,13 @@ export default async function InitializeServer(options: InitializationOptions) {
     registerAuthenticationRoutes(server);
     registerCorsProxy(server);
 
-    const isRelease = determineEnvironment(); //vs. dev mode
+    const isRelease = determineEnvironment();
     routeSetter(new RouteManager(server, isRelease));
 
-    server.listen(listenAtPort, () => logPort("server", listenAtPort));
+    server.listen(listenAtPort, () => {
+        logPort("server", listenAtPort);
+        console.log();
+    });
     return isRelease;
 }
 
@@ -92,8 +96,9 @@ function buildWithMiddleware(server: express.Express) {
 function determineEnvironment() {
     const isRelease = process.env.RELEASE === "true";
 
-    console.log(`running server in ${isRelease ? 'release' : 'debug'} mode`);
-    console.log(process.env.PWD);
+    const color = isRelease ? blue : yellow;
+    const label = isRelease ? "release" : "development";
+    console.log(`\nrunning server in ${color(label)} mode`);
 
     let clientUtils = fs.readFileSync("./src/client/util/ClientUtils.ts.temp", "utf8");
     clientUtils = `//AUTO-GENERATED FILE: DO NOT EDIT\n${clientUtils.replace('"mode"', String(isRelease))}`;
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 7c49485f1..3af36d879 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -1,7 +1,7 @@
 import RouteSubscriber from "./RouteSubscriber";
 import { DashUserModel } from "./authentication/models/user_model";
 import * as express from 'express';
-import { ConsoleColors } from "./ActionUtilities";
+import { yellow, cyan, red } from 'colors';
 
 export enum Method {
     GET,
@@ -41,6 +41,12 @@ export default class RouteManager {
         this._isRelease = isRelease;
     }
 
+    log = () => {
+        console.log(yellow("\nthe following server routes have been registered:"));
+        Array.from(registered.keys()).sort().forEach(route => console.log(cyan(route)));
+        console.log();
+    }
+
     /**
      * 
      * @param initializer 
@@ -48,14 +54,14 @@ export default class RouteManager {
     addSupervisedRoute = (initializer: RouteInitializer): void => {
         const { method, subscription, onValidation, onUnauthenticated, onError } = initializer;
         const isRelease = this._isRelease;
-        let supervised = async (req: express.Request, res: express.Response) => {
+        const supervised = async (req: express.Request, res: express.Response) => {
             const { user, originalUrl: target } = req;
             const core = { req, res, isRelease };
             const tryExecute = async (toExecute: (args: any) => any | Promise<any>, args: any) => {
                 try {
                     await toExecute(args);
                 } catch (e) {
-                    console.log(ConsoleColors.Red, target, user?.email ?? "<user logged out>");
+                    console.log(red(target), user?.email ?? "<user logged out>");
                     if (onError) {
                         onError({ ...core, error: e });
                     } else {
@@ -78,7 +84,7 @@ export default class RouteManager {
             }
             setTimeout(() => {
                 if (!res.headersSent) {
-                    console.log("Initiating fallback for ", target);
+                    console.log(`Initiating fallback for ${target}`);
                     const warning = `request to ${target} fell through - this is a fallback response`;
                     res.send({ warning });
                 }
@@ -94,7 +100,7 @@ export default class RouteManager {
             const existing = registered.get(route);
             if (existing) {
                 if (existing.has(method)) {
-                    console.log(ConsoleColors.Red, `\nDuplicate registration error: already registered ${route} with Method[${method}]`);
+                    console.log(red(`\nDuplicate registration error: already registered ${route} with Method[${method}]`));
                     console.log('Please remove duplicate registrations before continuing...\n');
                     process.exit(0);
                 }
diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts
index fbf71f707..2eb764945 100644
--- a/src/server/Websocket/Websocket.ts
+++ b/src/server/Websocket/Websocket.ts
@@ -7,12 +7,13 @@ import { Search } from "../Search";
 import * as io from 'socket.io';
 import YoutubeApi from "../apis/youtube/youtubeApiSample";
 import { GoogleCredentialsLoader } from "../credentials/CredentialsLoader";
-import { ConsoleColors, logPort } from "../ActionUtilities";
+import { logPort } from "../ActionUtilities";
 import { timeMap } from "../ApiManagers/UserManager";
+import { green } from "colors";
 
 export namespace WebSocket {
 
-    let clients: { [key: string]: Client } = {};
+    const clients: { [key: string]: Client } = {};
     export const socketMap = new Map<SocketIO.Socket, string>();
 
     export async function start(serverPort: number, isRelease: boolean) {
@@ -27,7 +28,7 @@ export namespace WebSocket {
         const endpoint = io();
         endpoint.on("connection", function (socket: Socket) {
             socket.use((_packet, next) => {
-                let userEmail = socketMap.get(socket);
+                const userEmail = socketMap.get(socket);
                 if (userEmail) {
                     timeMap[userEmail] = Date.now();
                 }
@@ -85,7 +86,7 @@ export namespace WebSocket {
 
     function barReceived(socket: SocketIO.Socket, userEmail: string) {
         clients[userEmail] = new Client(userEmail.toString());
-        console.log(ConsoleColors.Green, `user ${userEmail} has connected to the web socket`);
+        console.log(green(`user ${userEmail} has connected to the web socket`));
         socketMap.set(socket, userEmail);
     }
 
@@ -178,12 +179,12 @@ export namespace WebSocket {
         for (let key in docfield) {
             if (!key.startsWith("fields.")) continue;
             dynfield = true;
-            let val = docfield[key];
+            const val = docfield[key];
             key = key.substring(7);
             Object.values(suffixMap).forEach(suf => update[key + getSuffix(suf)] = { set: null });
-            let term = ToSearchTerm(val);
+            const term = ToSearchTerm(val);
             if (term !== undefined) {
-                let { suffix, value } = term;
+                const { suffix, value } = term;
                 update[key + suffix] = { set: value };
             }
         }
diff --git a/src/server/apis/google/GoogleApiServerUtils.ts b/src/server/apis/google/GoogleApiServerUtils.ts
index b0f3ba993..329107a71 100644
--- a/src/server/apis/google/GoogleApiServerUtils.ts
+++ b/src/server/apis/google/GoogleApiServerUtils.ts
@@ -135,7 +135,7 @@ export namespace GoogleApiServerUtils {
                 return resolve();
             }
             let routed: Opt<Endpoint>;
-            let parameters: any = { auth, version: "v1" };
+            const parameters: any = { auth, version: "v1" };
             switch (sector) {
                 case Service.Documents:
                     routed = google.docs(parameters).documents;
@@ -318,7 +318,7 @@ export namespace GoogleApiServerUtils {
      */
     async function retrieveCredentials(userId: string): Promise<{ credentials: Opt<Credentials>, refreshed: boolean }> {
         let credentials: Opt<Credentials> = await Database.Auxiliary.GoogleAuthenticationToken.Fetch(userId);
-        let refreshed = false;
+        const refreshed = false;
         if (!credentials) {
             return { credentials: undefined, refreshed };
         }
@@ -340,9 +340,9 @@ export namespace GoogleApiServerUtils {
      * @returns the updated credentials
      */
     async function refreshAccessToken(credentials: Credentials, userId: string): Promise<Credentials> {
-        let headerParameters = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } };
+        const headerParameters = { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } };
         const { client_id, client_secret } = GoogleCredentialsLoader.ProjectCredentials;
-        let url = `https://oauth2.googleapis.com/token?${qs.stringify({
+        const url = `https://oauth2.googleapis.com/token?${qs.stringify({
             refreshToken: credentials.refresh_token,
             client_id,
             client_secret,
diff --git a/src/server/authentication/config/passport.ts b/src/server/authentication/config/passport.ts
index 726df7fd7..2271109a5 100644
--- a/src/server/authentication/config/passport.ts
+++ b/src/server/authentication/config/passport.ts
@@ -40,7 +40,7 @@ export let isAuthenticated = (req: Request, res: Response, next: NextFunction) =
 export let isAuthorized = (req: Request, res: Response, next: NextFunction) => {
     const provider = req.path.split("/").slice(-1)[0];
 
-    if (_.find((req.user as any).tokens!, { kind: provider })) {
+    if (_.find(req.user?.tokens, { kind: provider })) {
         next();
     } else {
         res.redirect(`/auth/${provider}`);
diff --git a/src/server/authentication/controllers/user_controller.ts b/src/server/authentication/controllers/user_controller.ts
index 517353479..f0086d4ea 100644
--- a/src/server/authentication/controllers/user_controller.ts
+++ b/src/server/authentication/controllers/user_controller.ts
@@ -68,9 +68,9 @@ export let postSignup = (req: Request, res: Response, next: NextFunction) => {
 
 };
 
-let tryRedirectToTarget = (req: Request, res: Response) => {
+const tryRedirectToTarget = (req: Request, res: Response) => {
     if (req.session && req.session.target) {
-        let target = req.session.target;
+        const target = req.session.target;
         req.session.target = undefined;
         res.redirect(target);
     } else {
@@ -148,7 +148,6 @@ export let postForgot = function (req: Request, res: Response, next: NextFunctio
     const email = req.body.email;
     async.waterfall([
         function (done: any) {
-            let token: string;
             c.randomBytes(20, function (err: any, buffer: Buffer) {
                 if (err) {
                     done(null);
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index ac4462f78..50bfb4832 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -42,10 +42,10 @@ export class CurrentUserUtils {
 
     // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
     static setupCreatorButtons(doc: Doc) {
-        let notes = CurrentUserUtils.setupNoteTypes(doc);
+        const notes = CurrentUserUtils.setupNoteTypes(doc);
         doc.noteTypes = Docs.Create.TreeDocument(notes, { title: "Note Types", height: 75 });
         doc.activePen = doc;
-        let docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
+        const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "collection", icon: "folder", ignoreClick: true, drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: "freeform" })' },
             { title: "todo item", icon: "check", ignoreClick: true, drag: 'getCopy(this.dragFactory, true)', dragFactory: notes[notes.length - 1] },
             { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' },
@@ -278,7 +278,7 @@ export class CurrentUserUtils {
         if (this._northstarCatalog && CurrentUserUtils._northstarSchemas) {
             this._northstarCatalog.schemas!.push(schema);
             CurrentUserUtils._northstarSchemas.push(schemaDoc);
-            let schemas = Cast(CurrentUserUtils.UserDocument.DBSchemas, listSpec("string"), []);
+            const schemas = Cast(CurrentUserUtils.UserDocument.DBSchemas, listSpec("string"), []);
             schemas.push(schema.displayName!);
             CurrentUserUtils.UserDocument.DBSchemas = new List<string>(schemas);
         }
diff --git a/src/server/database.ts b/src/server/database.ts
index db81245c1..4039e6203 100644
--- a/src/server/database.ts
+++ b/src/server/database.ts
@@ -71,7 +71,7 @@ export namespace Database {
 
         public async update(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateWriteOpResult) => void, upsert = true, collectionName = Database.DocumentsCollection) {
             if (this.db) {
-                let collection = this.db.collection(collectionName);
+                const collection = this.db.collection(collectionName);
                 const prom = this.currentWrites[id];
                 let newProm: Promise<void>;
                 const run = (): Promise<void> => {
@@ -96,7 +96,7 @@ export namespace Database {
 
         public replace(id: string, value: any, callback: (err: mongodb.MongoError, res: mongodb.UpdateWriteOpResult) => void, upsert = true, collectionName = Database.DocumentsCollection) {
             if (this.db) {
-                let collection = this.db.collection(collectionName);
+                const collection = this.db.collection(collectionName);
                 const prom = this.currentWrites[id];
                 let newProm: Promise<void>;
                 const run = (): Promise<void> => {
diff --git a/src/server/downsize.ts b/src/server/downsize.ts
index ed68fbecc..cd0d83812 100644
--- a/src/server/downsize.ts
+++ b/src/server/downsize.ts
@@ -17,7 +17,7 @@ fs.readdir(folder, async (err, files) => {
     // });
     for (const file of files) {
         const filesplit = file.split(".");
-        let resizers = [
+        const resizers = [
             { resizer: sharp().resize(100, undefined, { withoutEnlargement: true }), suffix: "_s" },
             { resizer: sharp().resize(400, undefined, { withoutEnlargement: true }), suffix: "_m" },
             { resizer: sharp().resize(900, undefined, { withoutEnlargement: true }), suffix: "_l" },
diff --git a/src/server/index.ts b/src/server/index.ts
index d77923710..0e0bd0bd6 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -51,7 +51,7 @@ async function preliminaryFunctions() {
  * that will manage the registration of new routes
  * with the server
  */
-function routeSetter({ isRelease, addSupervisedRoute }: RouteManager) {
+function routeSetter({ isRelease, addSupervisedRoute, log }: RouteManager) {
     const managers = [
         new UserManager(),
         new UploadManager(),
@@ -67,6 +67,7 @@ function routeSetter({ isRelease, addSupervisedRoute }: RouteManager) {
 
     // initialize API Managers
     managers.forEach(manager => manager.register(addSupervisedRoute));
+    log();
 
     // initialize the web socket (bidirectional communication: if a user changes
     // a field on one client, that change must be broadcast to all other clients)
@@ -82,8 +83,8 @@ function routeSetter({ isRelease, addSupervisedRoute }: RouteManager) {
     });
 
     const serve: OnUnauthenticated = ({ req, res }) => {
-        let detector = new mobileDetect(req.headers['user-agent'] || "");
-        let filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html';
+        const detector = new mobileDetect(req.headers['user-agent'] || "");
+        const filename = detector.mobile() !== null ? 'mobile/image.html' : 'index.html';
         res.sendFile(path.join(__dirname, '../../deploy/' + filename));
     };
 
@@ -104,8 +105,8 @@ function routeSetter({ isRelease, addSupervisedRoute }: RouteManager) {
 
 (async function start() {
     await log_execution({
-        startMessage: "starting execution of preliminary functions",
-        endMessage: "completed preliminary functions",
+        startMessage: "\nstarting execution of preliminary functions",
+        endMessage: "completed preliminary functions\n",
         action: preliminaryFunctions
     });
     await initializeServer({ listenAtPort: 1050, routeSetter });
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index 36d828fdb..9e8ace962 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -1,6 +1,7 @@
 /// <reference types="node" />
 
 declare module 'googlephotos';
+declare module 'react-image-lightbox-with-rotate';
 
 declare module '@react-pdf/renderer' {
     import * as React from 'react';
diff --git a/test/test.ts b/test/test.ts
index f1cf75bd4..245733e9b 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -14,21 +14,21 @@ import { createSchema, makeInterface, defaultSpec } from '../src/new_fields/Sche
 import { ImageField } from '../src/new_fields/URLField';
 describe("Document", () => {
     it('should hold fields', () => {
-        let key = "Test";
-        let key2 = "Test2";
-        let field = 15;
-        let doc = new Doc();
+        const key = "Test";
+        const key2 = "Test2";
+        const field = 15;
+        const doc = new Doc();
         doc[key] = field;
-        let getField = Cast(doc[key], "number");
-        let getField2 = Cast(doc[key2], "number");
+        const getField = Cast(doc[key], "number");
+        const getField2 = Cast(doc[key2], "number");
         expect(getField).to.equal(field);
         expect(getField2).to.equal(undefined);
     });
 
     it('should update', () => {
-        let doc = new Doc();
-        let key = "Test";
-        let key2 = "Test2";
+        const doc = new Doc();
+        const key = "Test";
+        const key2 = "Test2";
         let ran = false;
         reaction(() => doc[key], (field) => { ran = true; });
         expect(ran).to.equal(false);
diff --git a/tslint.json b/tslint.json
index 76d28b375..0056f4266 100644
--- a/tslint.json
+++ b/tslint.json
@@ -1,32 +1,18 @@
 {
+    "linterOptions": {
+        "exclude": ["./src/client/northstar/**", "**/*.js"]
+    },
     "rules": {
-        // "no-non-null-assertion": true,
         "no-return-await": true,
         "no-string-literal": true,
-        // "no-var-keyword": true,
-        // "no-var-requires": true,
         "prefer-object-spread": true,
         "prefer-for-of": true,
         "no-unnecessary-type-assertion": true,
-        // "no-void-expression": [
-        //     true,
-        //     "ignore-arrow-function-shorthand"
-        // ],
         "triple-equals": true,
-        // "prefer-const": true,
+        "prefer-const": true,
         "no-unnecessary-callback-wrapper": true,
-        // "align": [
-        //     true,
-        //     "parameters",
-        //     "arguments",
-        //     "statements",
-        //     "members",
-        //     "elements"
-        // ],
         "class-name": true,
         "arrow-return-shorthand": true,
-        // "object-literal-shorthand": true,
-        // "object-literal-sort-keys": true,
         "semicolon": [
             true,
             "always"
@@ -35,13 +21,6 @@
             true,
             "ignore-same-line"
         ],
-        // "quotemark": [
-        //     true,
-        //     "double",
-        //     "jsx-double",
-        //     "avoid-template",
-        //     "avoid-escape"
-        // ],
         "no-tautology-expression": true,
         "unnecessary-constructor": true
         // "trailing-comma": [
@@ -52,6 +31,33 @@
         //     }
         // ],
         // "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"
+    "defaultSeverity": "warning",
+    "jsRules": {
+
+    }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 968d678e8aeb6f57cc892e3fe789067a8246c5fe Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 4 Dec 2019 17:47:28 -0500
Subject: started to add paths

---
 src/client/documents/Documents.ts                  |  5 +--
 src/client/util/RichTextSchema.tsx                 |  3 +-
 src/client/views/CollectionLinearView.tsx          |  1 +
 src/client/views/MainView.tsx                      | 11 ++++---
 src/client/views/OverlayView.tsx                   |  1 +
 .../views/collections/CollectionDockingView.tsx    | 38 +++++++++++++---------
 .../views/collections/CollectionSchemaView.tsx     |  1 +
 .../views/collections/CollectionStackingView.tsx   |  1 +
 .../views/collections/CollectionTreeView.tsx       | 36 +++++++++++---------
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  1 +
 .../views/nodes/ContentFittingDocumentView.tsx     |  4 ++-
 src/client/views/nodes/DocumentView.tsx            | 12 ++++---
 src/client/views/nodes/FieldView.tsx               |  1 +
 src/client/views/nodes/FormattedTextBoxComment.tsx |  3 +-
 .../views/presentationview/PresElementBox.tsx      |  3 +-
 src/client/views/search/SearchItem.tsx             |  3 +-
 16 files changed, 78 insertions(+), 46 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e0f2858ba..5d5bdfcbd 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -534,7 +534,8 @@ export namespace Docs {
 
         export type DocConfig = {
             doc: Doc,
-            initialWidth?: number
+            initialWidth?: number,
+            path?: Doc[]
         };
 
         export function StandardCollectionDockingDocument(configs: Array<DocConfig>, options: DocumentOptions, id?: string, type: string = "row") {
@@ -543,7 +544,7 @@ export namespace Docs {
                     {
                         type: type,
                         content: [
-                            ...configs.map(config => CollectionDockingView.makeDocumentConfig(config.doc, undefined, config.initialWidth))
+                            ...configs.map(config => CollectionDockingView.makeDocumentConfig(config.doc, undefined, config.initialWidth, config.path))
                         ]
                     }
                 ]
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 3b786e61d..4612f2885 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -761,8 +761,9 @@ export class DashDocView {
                     this._dashSpan.style.width = this._outer.style.width = dashDoc[WidthSym]() + "px";
                 });
                 ReactDOM.render(<DocumentView
-                    fitToBox={BoolCast(dashDoc.fitToBox)}
                     Document={dashDoc}
+                    LibraryPath={tbox.props.LibraryPath}
+                    fitToBox={BoolCast(dashDoc.fitToBox)}
                     addDocument={returnFalse}
                     removeDocument={removeDoc}
                     ruleProvider={undefined}
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index 09e4ef99c..293a4feea 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -74,6 +74,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                             <DocumentView
                                 Document={pair.layout}
                                 DataDoc={pair.data}
+                                LibraryPath={this.props.LibraryPath}
                                 addDocument={this.props.addDocument}
                                 moveDocument={this.props.moveDocument}
                                 addDocTab={this.props.addDocTab}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 254b2e906..29719a6eb 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -198,8 +198,7 @@ export class MainView extends React.Component {
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
         Doc.AddDocToList(Doc.GetProto(CurrentUserUtils.UserDocument.documents as Doc), "data", freeformDoc);
-        const dockingLayout = { content: [{ type: 'row', content: [CollectionDockingView.makeDocumentConfig(freeformDoc, freeformDoc, 600)] }] };
-        const mainDoc = Docs.Create.DockDocument([freeformDoc], JSON.stringify(dockingLayout), { title: `Workspace ${workspaceCount}` }, id);
+        const mainDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600, path: [Doc.UserDoc().documents as Doc] }], { title: `Workspace ${workspaceCount}` }, id, "row");
         Doc.AddDocToList(workspaces, "data", mainDoc);
         // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
         setTimeout(() => this.openWorkspace(mainDoc), 0);
@@ -271,6 +270,7 @@ export class MainView extends React.Component {
                     {!mainContainer ? (null) :
                         <DocumentView Document={mainContainer}
                             DataDoc={undefined}
+                            LibraryPath={[]}
                             addDocument={undefined}
                             addDocTab={this.addDocTabFunc}
                             pinToPres={emptyFunction}
@@ -338,7 +338,7 @@ export class MainView extends React.Component {
         document.removeEventListener("pointerup", this.onPointerUp);
     }
     flyoutWidthFunc = () => this.flyoutWidth;
-    addDocTabFunc = (doc: Doc, data: Opt<Doc>, where: string) => {
+    addDocTabFunc = (doc: Doc, data: Opt<Doc>, where: string, libraryPath?: Doc[]) => {
         if (where === "close") {
             return CollectionDockingView.CloseRightSplit(doc);
         }
@@ -346,7 +346,7 @@ export class MainView extends React.Component {
             this.openWorkspace(doc);
             return true;
         } else {
-            return CollectionDockingView.AddRightSplit(doc, undefined);
+            return CollectionDockingView.AddRightSplit(doc, undefined, undefined, libraryPath);
         }
     }
     mainContainerXf = () => new Transform(0, -this._buttonBarHeight, 1);
@@ -363,6 +363,7 @@ export class MainView extends React.Component {
                 <DocumentView
                     Document={sidebarButtonsDoc}
                     DataDoc={undefined}
+                    LibraryPath={[]}
                     addDocument={undefined}
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -389,6 +390,7 @@ export class MainView extends React.Component {
                 <DocumentView
                     Document={sidebarContent}
                     DataDoc={undefined}
+                    LibraryPath={[]}
                     addDocument={undefined}
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -474,6 +476,7 @@ export class MainView extends React.Component {
                 <CollectionLinearView
                     Document={CurrentUserUtils.UserDocument.expandingButtons}
                     DataDoc={undefined}
+                    LibraryPath={[]}
                     fieldKey={"data"}
                     annotationsKey={""}
                     select={emptyFunction}
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 32ada293c..9b42d199c 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -174,6 +174,7 @@ export class OverlayView extends React.Component {
             return <div className="overlayView-doc" key={d[Id]} onPointerDown={onPointerDown} style={{ transform: `translate(${d.x}px, ${d.y}px)`, display: d.isMinimized ? "none" : "" }}>
                 <DocumentView
                     Document={d}
+                    LibraryPath={[]}
                     ChromeHeight={returnZero}
                     // isSelected={returnFalse}
                     // select={emptyFunction}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 77e6e1c93..e35dc4c00 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -39,7 +39,7 @@ const _global = (window /* browser */ || global /* node */) as any;
 export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
     @observable public static Instances: CollectionDockingView[] = [];
     @computed public static get Instance() { return CollectionDockingView.Instances[0]; }
-    public static makeDocumentConfig(document: Doc, dataDoc: Doc | undefined, width?: number) {
+    public static makeDocumentConfig(document: Doc, dataDoc: Doc | undefined, width?: number, libraryPath?: Doc[]) {
         return {
             type: 'react-component',
             component: 'DocumentFrameRenderer',
@@ -47,7 +47,8 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             width: width,
             props: {
                 documentId: document[Id],
-                dataDocumentId: dataDoc && dataDoc[Id] !== document[Id] ? dataDoc[Id] : ""
+                dataDocumentId: dataDoc && dataDoc[Id] !== document[Id] ? dataDoc[Id] : "",
+                libraryPath: libraryPath ? libraryPath.map(d => d[Id]) : []
                 //collectionDockingView: CollectionDockingView.Instance
             }
         };
@@ -95,12 +96,12 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
     @undoBatch
     @action
-    public OpenFullScreen(docView: DocumentView) {
+    public OpenFullScreen(docView: DocumentView, libraryPath?: Doc[]) {
         const document = Doc.MakeAlias(docView.props.Document);
         const dataDoc = docView.props.DataDoc;
         const newItemStackConfig = {
             type: 'stack',
-            content: [CollectionDockingView.makeDocumentConfig(document, dataDoc)]
+            content: [CollectionDockingView.makeDocumentConfig(document, dataDoc, undefined, libraryPath)]
         };
         const docconfig = this._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, this._goldenLayout);
         this._goldenLayout.root.contentItems[0].addChild(docconfig);
@@ -174,12 +175,12 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
     //
     @undoBatch
     @action
-    public static AddRightSplit(document: Doc, dataDoc: Doc | undefined, minimize: boolean = false) {
+    public static AddRightSplit(document: Doc, dataDoc: Doc | undefined, minimize: boolean = false, libraryPath?: Doc[]) {
         if (!CollectionDockingView.Instance) return false;
         const instance = CollectionDockingView.Instance;
         const newItemStackConfig = {
             type: 'stack',
-            content: [CollectionDockingView.makeDocumentConfig(document, dataDoc)]
+            content: [CollectionDockingView.makeDocumentConfig(document, dataDoc, undefined, libraryPath)]
         };
 
         const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
@@ -211,9 +212,9 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
     @undoBatch
     @action
-    public AddTab = (stack: any, document: Doc, dataDocument: Doc | undefined) => {
+    public AddTab = (stack: any, document: Doc, dataDocument: Doc | undefined, libraryPath?: Doc[]) => {
         Doc.GetProto(document).lastOpened = new DateField;
-        const docContentConfig = CollectionDockingView.makeDocumentConfig(document, dataDocument);
+        const docContentConfig = CollectionDockingView.makeDocumentConfig(document, dataDocument, undefined, libraryPath);
         if (stack === undefined) {
             let stack: any = this._goldenLayout.root;
             while (!stack.isStack) {
@@ -427,10 +428,6 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                             });
                         }}><FontAwesomeIcon icon="file" size="lg" /></span>, dragSpan);
                 ReactDOM.render(<ButtonSelector Document={doc} Stack={stack} />, gearSpan);
-                // ReactDOM.render(<ParentDocSelector Document={doc} addDocTab={(doc, data, where) => {
-                //     where === "onRight" ? CollectionDockingView.AddRightSplit(doc, dataDoc) : CollectionDockingView.Instance.AddTab(stack, doc, dataDoc);
-                //     return true;
-                // }} />, upDiv);
                 tab.reactComponents = [dragSpan, gearSpan, upDiv];
                 tab.element.append(dragSpan);
                 tab.element.append(gearSpan);
@@ -532,11 +529,13 @@ interface DockedFrameProps {
     documentId: FieldId;
     dataDocumentId: FieldId;
     glContainer: any;
+    libraryPath: (FieldId[])
     //collectionDockingView: CollectionDockingView
 }
 @observer
 export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     _mainCont: HTMLDivElement | null = null;
+    @observable private _libraryPath: Doc[] = [];
     @observable private _panelWidth = 0;
     @observable private _panelHeight = 0;
     @observable private _document: Opt<Doc>;
@@ -554,6 +553,14 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
                 DocServer.GetRefField(this.props.dataDocumentId).then(action((f: Opt<Field>) => this._dataDoc = f as Doc));
             }
         }));
+        this.props.libraryPath && this.setupLibraryPath();
+    }
+
+    async setupLibraryPath() {
+        Promise.all(this.props.libraryPath.map(async docid => {
+            let d = await DocServer.GetRefField(docid);
+            return d instanceof Doc ? d : undefined
+        })).then(action((list: (Doc | undefined)[]) => this._libraryPath = list.filter(d => d).map(d => d as Doc)));
     }
 
     /**
@@ -640,17 +647,17 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     get previewPanelCenteringOffset() { return this.nativeWidth() && !this.layoutDoc!.ignoreAspect ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; }
     get widthpercent() { return this.nativeWidth() && !this.layoutDoc!.ignoreAspect ? `${(this.nativeWidth() * this.contentScaling()) / this.panelWidth() * 100}%` : undefined; }
 
-    addDocTab = (doc: Doc, dataDoc: Opt<Doc>, location: string) => {
+    addDocTab = (doc: Doc, dataDoc: Opt<Doc>, location: string, libraryPath?: Doc[]) => {
         SelectionManager.DeselectAll();
         if (doc.dockingConfig) {
             MainView.Instance.openWorkspace(doc);
             return true;
         } else if (location === "onRight") {
-            return CollectionDockingView.AddRightSplit(doc, dataDoc);
+            return CollectionDockingView.AddRightSplit(doc, dataDoc, undefined, libraryPath);
         } else if (location === "close") {
             return CollectionDockingView.CloseRightSplit(doc);
         } else {
-            return CollectionDockingView.Instance.AddTab(this._stack, doc, dataDoc);
+            return CollectionDockingView.Instance.AddTab(this._stack, doc, dataDoc, libraryPath);
         }
     }
 
@@ -659,6 +666,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
         const document = this._document;
         const resolvedDataDoc = document.layout instanceof Doc ? document : this._dataDoc;
         return <DocumentView key={document[Id]}
+            LibraryPath={this._libraryPath}
             Document={document}
             DataDoc={resolvedDataDoc}
             bringToFront={emptyFunction}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f336eaf75..8169e9e2b 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -141,6 +141,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             <ContentFittingDocumentView
                 Document={layoutDoc}
                 DataDocument={this.previewDocument !== this.props.DataDoc ? this.props.DataDoc : undefined}
+                LibraryPath={this.props.LibraryPath}
                 childDocs={this.childDocs}
                 renderDepth={this.props.renderDepth}
                 ruleProvider={this.props.Document.isRuleProvider && layoutDoc && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 955fcda80..9f01de08b 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -168,6 +168,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return <ContentFittingDocumentView
             Document={doc}
             DataDocument={dataDoc}
+            LibraryPath={this.props.LibraryPath}
             showOverlays={this.overlays}
             renderDepth={this.props.renderDepth}
             ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 95503147a..219d56607 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -33,6 +33,7 @@ import { CurrentUserUtils } from '../../../server/authentication/models/current_
 export interface TreeViewProps {
     document: Doc;
     dataDoc?: Doc;
+    libraryPath: Doc[] | undefined;
     containingCollection: Doc;
     prevSibling?: Doc;
     renderDepth: number;
@@ -40,7 +41,7 @@ export interface TreeViewProps {
     ruleProvider: Doc | undefined;
     moveDocument: DragManager.MoveFunction;
     dropAction: "alias" | "copy" | undefined;
-    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean;
+    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string, libraryPath?: Doc[]) => boolean;
     pinToPres: (document: Doc) => void;
     panelWidth: () => number;
     panelHeight: () => number;
@@ -95,8 +96,8 @@ class TreeView extends React.Component<TreeViewProps> {
     @computed get MAX_EMBED_HEIGHT() { return NumCast(this.props.document.maxEmbedHeight, 300); }
     @computed get dataDoc() { return this.templateDataDoc ? this.templateDataDoc : this.props.document; }
     @computed get fieldKey() {
-        const splits = StrCast(Doc.LayoutField(this.props.document)).split("fieldKey={\"");
-        return splits.length > 1 ? splits[1].split("\"")[0] : "data";
+        const splits = StrCast(Doc.LayoutField(this.props.document)).split("fieldKey={\'");
+        return splits.length > 1 ? splits[1].split("\'")[0] : "data";
     }
     childDocList(field: string) {
         const layout = Doc.LayoutField(this.props.document) instanceof Doc ? Doc.LayoutField(this.props.document) as Doc : undefined;
@@ -120,7 +121,7 @@ class TreeView extends React.Component<TreeViewProps> {
     }
 
     @undoBatch delete = () => this.props.deleteDoc(this.props.document);
-    @undoBatch openRight = () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight");
+    @undoBatch openRight = () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight", this.props.libraryPath);
     @undoBatch indent = () => this.props.addDocument(this.props.document) && this.delete();
     @undoBatch move = (doc: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
         return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc);
@@ -194,8 +195,8 @@ class TreeView extends React.Component<TreeViewProps> {
                 ContextMenu.Instance.addItem({ description: "Clear All", event: () => Doc.GetProto(CurrentUserUtils.UserDocument.recentlyClosed as Doc).data = new List<Doc>(), icon: "plus" });
             } else if (this.props.document !== CurrentUserUtils.UserDocument.workspaces) {
                 ContextMenu.Instance.addItem({ description: "Pin to Presentation", event: () => this.props.pinToPres(this.props.document), icon: "tv" });
-                ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "inTab"), icon: "folder" });
-                ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight"), icon: "caret-square-right" });
+                ContextMenu.Instance.addItem({ description: "Open Tab", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "inTab", this.props.libraryPath), icon: "folder" });
+                ContextMenu.Instance.addItem({ description: "Open Right", event: () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight", this.props.libraryPath), icon: "caret-square-right" });
                 if (DocumentManager.Instance.getDocumentViews(this.dataDoc).length) {
                     ContextMenu.Instance.addItem({ description: "Focus", event: () => (view => view && view.props.focus(this.props.document, true))(DocumentManager.Instance.getFirstDocumentView(this.dataDoc)), icon: "camera" });
                 }
@@ -286,7 +287,7 @@ class TreeView extends React.Component<TreeViewProps> {
                     DocListCast(contents), this.props.treeViewId, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
                     this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
-                    [...this.props.renderedIds, doc[Id]]);
+                    [...this.props.renderedIds, doc[Id]], this.props.libraryPath);
             } else {
                 contentElement = <EditableView
                     key="editableView"
@@ -331,7 +332,7 @@ class TreeView extends React.Component<TreeViewProps> {
                         this.templateDataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                         this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
                         this.props.outerXf, this.props.active, this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.hideHeaderFields, this.props.preventTreeViewOpen,
-                        [...this.props.renderedIds, this.props.document[Id]])}
+                        [...this.props.renderedIds, this.props.document[Id]], this.props.libraryPath)}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
             return <ul><div ref={this._dref} style={{ display: "inline-block" }} key={this.props.document[Id] + this.props.document.title}>
@@ -343,6 +344,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 <ContentFittingDocumentView
                     Document={layoutDoc}
                     DataDocument={this.templateDataDoc}
+                    LibraryPath={[]}
                     renderDepth={this.props.renderDepth}
                     showOverlays={this.noOverlays}
                     ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
@@ -445,7 +447,8 @@ class TreeView extends React.Component<TreeViewProps> {
         renderDepth: number,
         hideHeaderFields: () => boolean,
         preventTreeViewOpen: boolean,
-        renderedIds: string[]
+        renderedIds: string[],
+        libraryPath: Doc[] | undefined
     ) {
         const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
         if (viewSpecScript) {
@@ -499,9 +502,9 @@ class TreeView extends React.Component<TreeViewProps> {
             }
 
             const indent = i === 0 ? undefined : () => {
-                if (StrCast(docs[i - 1].layout).indexOf("fieldKey") !== -1) {
-                    const fieldKeysub = StrCast(docs[i - 1].layout).split("fieldKey")[1];
-                    const fieldKey = fieldKeysub.split("\"")[1];
+                if (StrCast(docs[i - 1].layout).indexOf('fieldKey') !== -1) {
+                    const fieldKeysub = StrCast(docs[i - 1].layout).split('fieldKey')[1];
+                    const fieldKey = fieldKeysub.split("\'")[1];
                     if (fieldKey && Cast(docs[i - 1][fieldKey], listSpec(Doc)) !== undefined) {
                         Doc.AddDocToList(docs[i - 1], fieldKey, child);
                         docs[i - 1].treeViewOpen = true;
@@ -510,9 +513,9 @@ class TreeView extends React.Component<TreeViewProps> {
                 }
             };
             const outdent = !parentCollectionDoc ? undefined : () => {
-                if (StrCast(parentCollectionDoc.layout).indexOf("fieldKey") !== -1) {
-                    const fieldKeysub = StrCast(parentCollectionDoc.layout).split("fieldKey")[1];
-                    const fieldKey = fieldKeysub.split("\"")[1];
+                if (StrCast(parentCollectionDoc.layout).indexOf('fieldKey') !== -1) {
+                    const fieldKeysub = StrCast(parentCollectionDoc.layout).split('fieldKey')[1];
+                    const fieldKey = fieldKeysub.split("\'")[1];
                     Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false);
                     parentCollectionDoc.treeViewOpen = true;
                     remove(child);
@@ -529,6 +532,7 @@ class TreeView extends React.Component<TreeViewProps> {
             return !(child instanceof Doc) ? (null) : <TreeView
                 document={pair.layout}
                 dataDoc={pair.data}
+                libraryPath={libraryPath ? [...libraryPath, containingCollection] : undefined}
                 containingCollection={containingCollection}
                 prevSibling={docs[i]}
                 treeViewId={treeViewId}
@@ -648,7 +652,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                         TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.Document, this.props.DataDoc, this.props.fieldKey, this.props.ContainingCollectionDoc, undefined, addDoc, this.remove,
                             moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.ScreenToLocalTransform,
                             this.outerXf, this.props.active, this.props.PanelWidth, this.props.ChromeHeight, this.props.renderDepth, () => BoolCast(this.props.Document.hideHeaderFields),
-                            BoolCast(this.props.Document.preventTreeViewOpen), [])
+                            BoolCast(this.props.Document.preventTreeViewOpen), [], this.props.LibraryPath)
                     }
                 </ul>
             </div >
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index c69b264c4..c3e064da5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -627,6 +627,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             ...this.props,
             DataDoc: childData,
             Document: childLayout,
+            LibraryPath: this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : [],
             layoutKey: undefined,
             ruleProvider: this.Document.isRuleProvider && childLayout.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider, //bcz: hack! - currently ruleProviders apply to documents in nested colleciton, not direct children of themselves
             onClick: undefined, // this.props.onClick,  // bcz: check this out -- I don't think we want to inherit click handlers, or we at least need a way to ignore them
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index efc907f9b..86fab0ba0 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -17,6 +17,7 @@ import { CollectionView } from "../collections/CollectionView";
 interface ContentFittingDocumentViewProps {
     Document?: Doc;
     DataDocument?: Doc;
+    LibraryPath: Doc[];
     childDocs?: Doc[];
     renderDepth: number;
     fitToBox?: boolean;
@@ -85,8 +86,9 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
                         width: `${100 * (this.props.PanelWidth() - this.centeringOffset * 2) / this.props.PanelWidth()}%`
                     }}>
                     <DocumentView {...this.props}
-                        DataDoc={this.props.DataDocument}
                         Document={this.props.Document}
+                        DataDoc={this.props.DataDocument}
+                        LibraryPath={this.props.LibraryPath}
                         fitToBox={this.props.fitToBox}
                         onClick={this.props.onClick}
                         ruleProvider={this.props.ruleProvider}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 63ce6233c..fef365bf3 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -54,6 +54,7 @@ export interface DocumentViewProps {
     ContainingCollectionDoc: Opt<Doc>;
     Document: Doc;
     DataDoc?: Doc;
+    LibraryPath: Doc[];
     fitToBox?: boolean;
     onClick?: ScriptField;
     addDocument?: (doc: Doc) => boolean;
@@ -70,7 +71,7 @@ export interface DocumentViewProps {
     parentActive: (outsideReaction: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
     bringToFront: (doc: Doc, sendToBack?: boolean) => void;
-    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => boolean;
+    addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string, libraryPath?: Doc[]) => boolean;
     pinToPres: (document: Doc) => void;
     zoomToScale: (scale: number) => void;
     backgroundColor: (doc: Doc) => string | undefined;
@@ -401,9 +402,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const cm = ContextMenu.Instance;
         const subitems: ContextMenuProps[] = [];
-        subitems.push({ description: "Open Full Screen", event: () => CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(this), icon: "desktop" });
-        subitems.push({ description: "Open Tab        ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "inTab"), icon: "folder" });
-        subitems.push({ description: "Open Right      ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "onRight"), icon: "caret-square-right" });
+        subitems.push({ description: "Open Full Screen", event: () => CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(this, this.props.LibraryPath), icon: "desktop" });
+        subitems.push({ description: "Open Tab        ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "inTab", this.props.LibraryPath), icon: "folder" });
+        subitems.push({ description: "Open Right      ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "onRight", this.props.LibraryPath), icon: "caret-square-right" });
         subitems.push({ description: "Open Alias Tab  ", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "inTab"), icon: "folder" });
         subitems.push({ description: "Open Alias Right", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "onRight"), icon: "caret-square-right" });
         subitems.push({ description: "Open Fields     ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" });
@@ -527,6 +528,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 SelectionManager.SelectDoc(this, false);
             }
         });
+        let path = this.props.LibraryPath.reduce((p: string, d: Doc) => p + "/" + (Doc.AreProtosEqual(d, (Doc.UserDoc().LibraryBtn as Doc).sourcePanel as Doc) ? "" : d.title), "");
+        cm.addItem({ description: `path: ${path}`, event: () => { }, icon: "check" })
     }
 
     // does Document set a layout prop 
@@ -552,6 +555,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             ContainingCollectionDoc={this.props.ContainingCollectionDoc}
             Document={this.props.Document}
             fitToBox={this.props.fitToBox}
+            LibraryPath={this.props.LibraryPath}
             addDocument={this.props.addDocument}
             removeDocument={this.props.removeDocument}
             moveDocument={this.props.moveDocument}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 048960c5e..ce1c468ad 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -30,6 +30,7 @@ export interface FieldViewProps {
     ruleProvider: Doc | undefined;
     Document: Doc;
     DataDoc?: Doc;
+    LibraryPath: Doc[];
     onClick?: ScriptField;
     isSelected: (outsideReaction?: boolean) => boolean;
     select: (isCtrlPressed: boolean) => void;
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index 2ec30e3b3..9f1dd4aec 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -177,8 +177,9 @@ export class FormattedTextBoxComment {
                             } catch (e) { }
                             if (target) {
                                 ReactDOM.render(<ContentFittingDocumentView
-                                    fitToBox={true}
                                     Document={target}
+                                    LibraryPath={[]}
+                                    fitToBox={true}
                                     moveDocument={returnFalse}
                                     getTransform={Transform.Identity}
                                     active={returnFalse}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 47f876ac2..cfb9319bb 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -170,8 +170,9 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
                 <ContentFittingDocumentView
-                    fitToBox={StrCast(this.targetDoc.type).indexOf(DocumentType.COL) !== -1}
                     Document={this.targetDoc}
+                    LibraryPath={[]}
+                    fitToBox={StrCast(this.targetDoc.type).indexOf(DocumentType.COL) !== -1}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ruleProvider={undefined}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 6ffff0562..0be583358 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -159,8 +159,9 @@ export class SearchItem extends React.Component<SearchItemProps> {
                 onPointerEnter={action(() => this._displayDim = this._useIcons ? 50 : Number(SEARCH_THUMBNAIL_SIZE))}
                 onPointerLeave={action(() => this._displayDim = 50)} >
                 <DocumentView
-                    fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
                     Document={this.props.doc}
+                    LibraryPath={[]}
+                    fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
                     ruleProvider={undefined}
-- 
cgit v1.2.3-70-g09d2


From 600d06a162b4489fd52d5809eb9f5a69f28618fc Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 6 Dec 2019 23:11:51 -0500
Subject: performance tuning for sidebar

---
 src/Utils.ts                                         |  2 ++
 src/client/views/MainView.tsx                        | 11 +++++------
 .../views/collections/CollectionStackingView.tsx     | 20 +++++++++++++-------
 .../CollectionStackingViewFieldColumn.tsx            |  6 +++---
 src/client/views/collections/CollectionView.tsx      |  2 ++
 src/client/views/nodes/DocumentContentsView.tsx      |  3 +++
 6 files changed, 28 insertions(+), 16 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index 7401ef981..2b15ad0f2 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -362,6 +362,8 @@ export function returnZero() { return 0; }
 
 export function returnEmptyString() { return ""; }
 
+export let emptyPath = [];
+
 export function emptyFunction() { }
 
 export function unimplementedFunction() { throw new Error("This function is not implemented, but should be."); }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 175af1abc..dacc9226e 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -15,7 +15,7 @@ import { List } from '../../new_fields/List';
 import { listSpec } from '../../new_fields/Schema';
 import { Cast, FieldValue, StrCast } from '../../new_fields/Types';
 import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
-import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils } from '../../Utils';
+import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, Utils, emptyPath } from '../../Utils';
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
 import { DocServer } from '../DocServer';
 import { Docs, DocumentOptions } from '../documents/Documents';
@@ -261,11 +261,10 @@ export class MainView extends React.Component {
     getPHeight = () => this._panelHeight;
     getContentsHeight = () => this._panelHeight - this._buttonBarHeight;
 
-    _emptyPath = [];
     @computed get mainDocView() {
         return <DocumentView Document={this.mainContainer!}
             DataDoc={undefined}
-            LibraryPath={this._emptyPath}
+            LibraryPath={emptyPath}
             addDocument={undefined}
             addDocTab={this.addDocTabFunc}
             pinToPres={emptyFunction}
@@ -367,7 +366,7 @@ export class MainView extends React.Component {
                 <DocumentView
                     Document={sidebarButtonsDoc}
                     DataDoc={undefined}
-                    LibraryPath={[]}
+                    LibraryPath={emptyPath}
                     addDocument={undefined}
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -394,7 +393,7 @@ export class MainView extends React.Component {
                 <DocumentView
                     Document={sidebarContent}
                     DataDoc={undefined}
-                    LibraryPath={[]}
+                    LibraryPath={emptyPath}
                     addDocument={undefined}
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
@@ -478,7 +477,7 @@ export class MainView extends React.Component {
                 <CollectionLinearView
                     Document={CurrentUserUtils.UserDocument.expandingButtons}
                     DataDoc={undefined}
-                    LibraryPath={[]}
+                    LibraryPath={emptyPath}
                     fieldKey={"data"}
                     annotationsKey={""}
                     select={emptyFunction}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 9f01de08b..ff3417b77 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -24,6 +24,7 @@ import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
+import { TraceMobx } from "../../../new_fields/util";
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -383,17 +384,22 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         }
     }
 
+    @computed get renderedSections() {
+        TraceMobx();
+        let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
+        if (this.sectionFilter) {
+            const entries = Array.from(this.Sections.entries());
+            sections = entries.sort(this.sortFunc);
+        }
+        return sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]));
+    }
     render() {
+        TraceMobx();
         const editableViewProps = {
             GetValue: () => "",
             SetValue: this.addGroup,
             contents: "+ ADD A GROUP"
         };
-        let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
-        if (this.sectionFilter) {
-            const entries = Array.from(this.Sections.entries());
-            sections = entries.sort(this.sortFunc);
-        }
         return (
             <div className="collectionStackingMasonry-cont" >
                 <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
@@ -401,8 +407,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
                     onDrop={this.onDrop.bind(this)}
                     onContextMenu={this.onContextMenu}
-                    onWheel={(e: React.WheelEvent) => e.stopPropagation()} >
-                    {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))}
+                    onWheel={e => e.stopPropagation()} >
+                    {this.renderedSections}
                     {!this.showAddAGroup ? (null) :
                         <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
                             style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 80dc482af..ca3b93bf8 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -17,6 +17,7 @@ import { anchorPoints, Flyout } from "../DocumentDecorations";
 import { EditableView } from "../EditableView";
 import { CollectionStackingView } from "./CollectionStackingView";
 import "./CollectionStackingView.scss";
+import { TraceMobx } from "../../../new_fields/util";
 
 library.add(faPalette);
 
@@ -252,13 +253,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @observable private collapsed: boolean = false;
 
-    private toggleVisibility = action(() => {
-        this.collapsed = !this.collapsed;
-    });
+    private toggleVisibility = action(() => this.collapsed = !this.collapsed);
 
     @observable _headingsHack: number = 1;
 
     render() {
+        TraceMobx();
         const cols = this.props.cols();
         const key = StrCast(this.props.parent.props.Document.sectionFilter);
         let templatecols = "";
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index cd546696f..411040332 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -32,6 +32,7 @@ import { SelectionManager } from '../../util/SelectionManager';
 import './CollectionView.scss';
 import { FieldViewProps, FieldView } from '../nodes/FieldView';
 import { Touchable } from '../Touchable';
+import { TraceMobx } from '../../../new_fields/util';
 const path = require('path');
 library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
 
@@ -251,6 +252,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
             onMoveNextRequest={action(() => this._curLightboxImg = (this._curLightboxImg + 1) % images.length)} />);
     }
     render() {
+        TraceMobx();
         const props: CollectionRenderProps = {
             addDocument: this.addDocument,
             removeDocument: this.removeDocument,
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 13fd3cde1..1bbc82119 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -32,6 +32,7 @@ import { VideoBox } from "./VideoBox";
 import { WebBox } from "./WebBox";
 import { InkingStroke } from "../InkingStroke";
 import React = require("react");
+import { TraceMobx } from "../../../new_fields/util";
 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
@@ -57,6 +58,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     hideOnLeave?: boolean
 }> {
     @computed get layout(): string {
+        TraceMobx();
         if (!this.layoutDoc) return "<p>awaiting layout</p>";
         const layout = Cast(this.layoutDoc[this.props.layoutKey], "string");
         if (layout === undefined) {
@@ -92,6 +94,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
     }
 
     render() {
+        TraceMobx();
         return (this.props.renderDepth > 7 || !this.layout) ? (null) :
             <ObserverJsxParser
                 blacklistedAttrs={[]}
-- 
cgit v1.2.3-70-g09d2


From 860c7907268874f1754dd86bc3a984066552db12 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 12 Dec 2019 15:02:22 -0500
Subject: major changes to drag and drop

---
 src/client/northstar/dash-nodes/HistogramBox.tsx   |  12 +-
 src/client/util/DocumentManager.ts                 |   4 +-
 src/client/util/DragManager.ts                     | 386 ++++++++-------------
 src/client/util/LinkManager.ts                     |   6 +-
 src/client/views/CollectionLinearView.tsx          |   2 +-
 src/client/views/DocComponent.tsx                  |   2 +-
 src/client/views/DocumentButtonBar.tsx             |  37 +-
 src/client/views/DocumentDecorations.tsx           |   2 +-
 src/client/views/MainView.tsx                      |   2 +-
 src/client/views/OverlayView.tsx                   |   2 -
 src/client/views/TemplateMenu.tsx                  |  11 +-
 .../views/collections/CollectionDockingView.tsx    |  20 +-
 .../collections/CollectionMasonryViewFieldRow.tsx  |  14 +-
 .../views/collections/CollectionSchemaCells.tsx    |  21 +-
 .../CollectionSchemaMovableTableHOC.tsx            |  33 +-
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 .../views/collections/CollectionStackingView.tsx   |  24 +-
 .../CollectionStackingViewFieldColumn.tsx          |   8 +-
 src/client/views/collections/CollectionSubView.tsx |  31 +-
 .../views/collections/CollectionTreeView.tsx       |  28 +-
 src/client/views/collections/CollectionView.tsx    |   4 +-
 .../views/collections/CollectionViewChromes.tsx    |   6 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  33 +-
 src/client/views/linking/LinkMenu.scss             |  85 -----
 src/client/views/linking/LinkMenuGroup.tsx         |  28 +-
 src/client/views/linking/LinkMenuItem.scss         |  87 +++++
 src/client/views/linking/LinkMenuItem.tsx          |  24 +-
 src/client/views/nodes/ButtonBox.tsx               |   9 +-
 .../views/nodes/ContentFittingDocumentView.tsx     |   7 +-
 src/client/views/nodes/DocuLinkBox.tsx             |   4 +-
 src/client/views/nodes/DocumentView.tsx            |  33 +-
 src/client/views/nodes/FieldView.tsx               |   2 +-
 src/client/views/nodes/FormattedTextBox.tsx        |  14 +-
 src/client/views/nodes/ImageBox.tsx                |  10 +-
 src/client/views/pdf/PDFViewer.tsx                 |  12 +-
 src/client/views/search/SearchBox.tsx              |   2 -
 src/client/views/search/SearchItem.tsx             |  10 +-
 37 files changed, 446 insertions(+), 571 deletions(-)
 create mode 100644 src/client/views/linking/LinkMenuItem.scss

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/northstar/dash-nodes/HistogramBox.tsx b/src/client/northstar/dash-nodes/HistogramBox.tsx
index 854135648..8fee53fb9 100644
--- a/src/client/northstar/dash-nodes/HistogramBox.tsx
+++ b/src/client/northstar/dash-nodes/HistogramBox.tsx
@@ -46,8 +46,8 @@ export class HistogramBox extends React.Component<FieldViewProps> {
 
     @action
     dropX = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
-            let h = Cast(de.data.draggedDocuments[0].data, HistogramField);
+        if (de.complete.docDragData) {
+            let h = Cast(de.complete.docDragData.draggedDocuments[0].data, HistogramField);
             if (h) {
                 this.HistoOp.X = h.HistoOp.X;
             }
@@ -57,8 +57,8 @@ export class HistogramBox extends React.Component<FieldViewProps> {
     }
     @action
     dropY = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
-            let h = Cast(de.data.draggedDocuments[0].data, HistogramField);
+        if (de.complete.docDragData) {
+            let h = Cast(de.complete.docDragData.draggedDocuments[0].data, HistogramField);
             if (h) {
                 this.HistoOp.Y = h.HistoOp.X;
             }
@@ -78,10 +78,10 @@ export class HistogramBox extends React.Component<FieldViewProps> {
 
     componentDidMount() {
         if (this._dropXRef.current) {
-            this._dropXDisposer = DragManager.MakeDropTarget(this._dropXRef.current, { handlers: { drop: this.dropX.bind(this) } });
+            this._dropXDisposer = DragManager.MakeDropTarget(this._dropXRef.current, this.dropX.bind(this));
         }
         if (this._dropYRef.current) {
-            this._dropYDisposer = DragManager.MakeDropTarget(this._dropYRef.current, { handlers: { drop: this.dropY.bind(this) } });
+            this._dropYDisposer = DragManager.MakeDropTarget(this._dropYRef.current, this.dropY.bind(this));
         }
         reaction(() => CurrentUserUtils.NorthstarDBCatalog, (catalog?: Catalog) => this.activateHistogramOperation(catalog), { fireImmediately: true });
         reaction(() => [this.VisualBinRanges && this.VisualBinRanges.slice()], () => this.SizeConverter.SetVisualBinRanges(this.VisualBinRanges));
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 07247b7e9..6f65e6c68 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -108,7 +108,7 @@ export class DocumentManager {
                 return init && rest;
             })
         ).reduce((pairs, dv) => {
-            const linksList = LinkManager.Instance.getAllRelatedLinks(dv.props.Document);
+            const linksList = DocListCast(dv.props.Document.links);
             pairs.push(...linksList.reduce((pairs, link) => {
                 const linkToDoc = link && LinkManager.Instance.getOppositeAnchor(link, dv.props.Document);
                 linkToDoc && DocumentManager.Instance.getDocumentViews(linkToDoc).map(docView1 => {
@@ -176,7 +176,7 @@ export class DocumentManager {
     }
 
     public async FollowLink(link: Doc | undefined, doc: Doc, focus: (doc: Doc, maxLocation: string) => void, zoom: boolean = false, reverse: boolean = false, currentContext?: Doc) {
-        const linkDocs = link ? [link] : LinkManager.Instance.getAllRelatedLinks(doc);
+        const linkDocs = link ? [link] : DocListCast(doc.links);
         SelectionManager.DeselectAll();
         const firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc));
         const secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc));
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 9e6224d97..95529311a 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,5 +1,4 @@
-import { action, runInAction } from "mobx";
-import { Doc, Field } from "../../new_fields/Doc";
+import { Doc, Field, DocListCast } from "../../new_fields/Doc";
 import { Cast, ScriptCast } from "../../new_fields/Types";
 import { emptyFunction } from "../../Utils";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
@@ -22,7 +21,7 @@ export function SetupDrag(
     docFunc: () => Doc | Promise<Doc>,
     moveFunc?: DragManager.MoveFunction,
     dropAction?: dropActionType,
-    options?: any,
+    treeViewId?: string,
     dontHideOnDrop?: boolean,
     dragStarted?: () => void
 ) {
@@ -36,7 +35,7 @@ export function SetupDrag(
         const dragData = new DragManager.DocumentDragData([doc]);
         dragData.dropAction = dropAction;
         dragData.moveDocument = moveFunc;
-        dragData.options = options;
+        dragData.treeViewId = treeViewId;
         dragData.dontHideOnDrop = dontHideOnDrop;
         DragManager.StartDocumentDrag([_reference.current!], dragData, e.x, e.y);
         dragStarted && dragStarted();
@@ -65,62 +64,9 @@ export function SetupDrag(
     return onItemDown;
 }
 
-function moveLinkedDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
-    const document = SelectionManager.SelectedDocuments()[0];
-    document && document.props.removeDocument && document.props.removeDocument(doc);
-    addDocument(doc);
-    return true;
-}
-
-export async function DragLinkAsDocument(dragEle: HTMLElement, x: number, y: number, linkDoc: Doc, sourceDoc: Doc) {
-    const draggeddoc = LinkManager.Instance.getOppositeAnchor(linkDoc, sourceDoc);
-    if (draggeddoc) {
-        const moddrag = await Cast(draggeddoc.annotationOn, Doc);
-        const dragdocs = moddrag ? [moddrag] : [draggeddoc];
-        const dragData = new DragManager.DocumentDragData(dragdocs);
-        dragData.moveDocument = moveLinkedDocument;
-        DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
-            handlers: {
-                dragComplete: action(emptyFunction),
-            },
-            hideSource: false
-        });
-    }
-}
-
-export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Doc, singleLink?: Doc) {
-    const srcTarg = sourceDoc.proto;
-    let draggedDocs: Doc[] = [];
-
-    if (srcTarg) {
-        const linkDocs = singleLink ? [singleLink] : LinkManager.Instance.getAllRelatedLinks(srcTarg);
-        if (linkDocs) {
-            draggedDocs = linkDocs.map(link => {
-                const opp = LinkManager.Instance.getOppositeAnchor(link, sourceDoc);
-                if (opp) return opp;
-            }) as Doc[];
-        }
-    }
-    if (draggedDocs.length) {
-        const moddrag: Doc[] = [];
-        for (const draggedDoc of draggedDocs) {
-            const doc = await Cast(draggedDoc.annotationOn, Doc);
-            if (doc) moddrag.push(doc);
-        }
-        const dragdocs = moddrag.length ? moddrag : draggedDocs;
-        const dragData = new DragManager.DocumentDragData(dragdocs);
-        dragData.moveDocument = moveLinkedDocument;
-        DragManager.StartLinkedDocumentDrag([dragEle], dragData, x, y, {
-            handlers: {
-                dragComplete: action(emptyFunction),
-            },
-            hideSource: false
-        });
-    }
-}
-
-
 export namespace DragManager {
+    let dragDiv: HTMLDivElement;
+
     export function Root() {
         const root = document.getElementById("root");
         if (!root) {
@@ -128,79 +74,45 @@ export namespace DragManager {
         }
         return root;
     }
+    export let AbortDrag: () => void = emptyFunction;
+    export type MoveFunction = (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
 
-    let dragDiv: HTMLDivElement;
-
-    export enum DragButtons {
-        Left = 1,
-        Right = 2,
-        Both = Left | Right
-    }
-
-    interface DragOptions {
-        handlers: DragHandlers;
-
-        hideSource: boolean | (() => boolean);
-
-        dragHasStarted?: () => void;
-
-        withoutShiftDrag?: boolean;
-
-        finishDrag?: (dropData: { [id: string]: any }) => void;
-
-        offsetX?: number;
-
+    export interface DragDropDisposer { (): void; }
+    export interface DragOptions {
+        dragComplete?: (e: DragCompleteEvent) => void; // function to invoke when drag has completed
+        hideSource?: boolean;  // hide source document during drag
+        offsetX?: number;      // offset of top left of source drag visual from cursor
         offsetY?: number;
     }
 
-    export interface DragDropDisposer {
-        (): void;
-    }
-
-    export class DragCompleteEvent { }
-
-    export interface DragHandlers {
-        dragComplete: (e: DragCompleteEvent) => void;
-    }
-
-    export interface DropOptions {
-        handlers: DropHandlers;
-    }
+    // event called when the drag operation results in a drop action
     export class DropEvent {
         constructor(
             readonly x: number,
             readonly y: number,
-            readonly data: { [id: string]: any },
-            readonly mods: string
+            readonly complete: DragCompleteEvent,
+            readonly altKey: boolean,
+            readonly metaKey: boolean,
+            readonly ctrlKey: boolean
         ) { }
     }
 
-    export interface DropHandlers {
-        drop: (e: Event, de: DropEvent) => void;
-    }
-
-    export function MakeDropTarget(
-        element: HTMLElement,
-        options: DropOptions
-    ): DragDropDisposer {
-        if ("canDrop" in element.dataset) {
-            throw new Error(
-                "Element is already droppable, can't make it droppable again"
-            );
+    // event called when the drag operation has completed (aborted or completed a drop) -- this will be after any drop event has been generated
+    export class DragCompleteEvent {
+        constructor(aborted: boolean, dragData: { [id: string]: any }) {
+            this.aborted = aborted;
+            this.docDragData = dragData instanceof DocumentDragData ? dragData as DocumentDragData : undefined;
+            this.annoDragData = dragData instanceof PdfAnnoDragData ? dragData as PdfAnnoDragData : undefined;
+            this.linkDragData = dragData instanceof LinkDragData ? dragData as LinkDragData : undefined;
+            this.columnDragData = dragData instanceof ColumnDragData ? dragData as ColumnDragData : undefined;
         }
-        element.dataset.canDrop = "true";
-        const handler = (e: Event) => {
-            const ce = e as CustomEvent<DropEvent>;
-            options.handlers.drop(e, ce.detail);
-        };
-        element.addEventListener("dashOnDrop", handler);
-        return () => {
-            element.removeEventListener("dashOnDrop", handler);
-            delete element.dataset.canDrop;
-        };
+        aborted: boolean;
+        docDragData?: DocumentDragData;
+        annoDragData?: PdfAnnoDragData;
+        linkDragData?: LinkDragData;
+        columnDragData?: ColumnDragData;
     }
 
-    export type MoveFunction = (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     export class DocumentDragData {
         constructor(dragDoc: Doc[]) {
             this.draggedDocuments = dragDoc;
@@ -210,6 +122,8 @@ export namespace DragManager {
         draggedDocuments: Doc[];
         droppedDocuments: Doc[];
         dragDivName?: string;
+        treeViewId?: string;
+        dontHideOnDrop?: boolean;
         offset: number[];
         dropAction: dropActionType;
         userDropAction: dropActionType;
@@ -217,16 +131,34 @@ export namespace DragManager {
         moveDocument?: MoveFunction;
         isSelectionMove?: boolean; // indicates that an explicitly selected Document is being dragged.  this will suppress onDragStart scripts
         applyAsTemplate?: boolean;
+    }
+    export class LinkDragData {
+        constructor(linkSourceDoc: Doc) {
+            this.linkSourceDocument = linkSourceDoc;
+        }
+        droppedDocuments: Doc[] = [];
+        linkSourceDocument: Doc;
+        dontClearTextBox?: boolean;
+        linkDocument?: Doc;
         [id: string]: any;
     }
-
-    export class AnnotationDragData {
+    export class ColumnDragData {
+        constructor(colKey: SchemaHeaderField) {
+            this.colKey = colKey;
+        }
+        colKey: SchemaHeaderField;
+        [id: string]: any;
+    }
+    // used by PDFs to conditionally (if the drop completes) create a text annotation when dragging from the PDF toolbar when a text region has been selected.
+    // this is pretty clunky and should be rethought out using linkDrag or DocumentDrag
+    export class PdfAnnoDragData {
         constructor(dragDoc: Doc, annotationDoc: Doc, dropDoc: Doc) {
             this.dragDocument = dragDoc;
             this.dropDocument = dropDoc;
             this.annotationDocument = annotationDoc;
             this.offset = [0, 0];
         }
+        linkedToDoc?: boolean;
         targetContext: Doc | undefined;
         dragDocument: Doc;
         annotationDocument: Doc;
@@ -236,98 +168,103 @@ export namespace DragManager {
         userDropAction: dropActionType;
     }
 
-    export let StartDragFunctions: (() => void)[] = [];
+    export function MakeDropTarget(
+        element: HTMLElement,
+        dropFunc: (e: Event, de: DropEvent) => void
+    ): DragDropDisposer {
+        if ("canDrop" in element.dataset) {
+            throw new Error(
+                "Element is already droppable, can't make it droppable again"
+            );
+        }
+        element.dataset.canDrop = "true";
+        const handler = (e: Event) => dropFunc(e, (e as CustomEvent<DropEvent>).detail);
+        element.addEventListener("dashOnDrop", handler);
+        return () => {
+            element.removeEventListener("dashOnDrop", handler);
+            delete element.dataset.canDrop;
+        };
+    }
 
+    // drag a document and drop it (or make an alias/copy on drop)
     export function StartDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
-        runInAction(() => StartDragFunctions.map(func => func()));
+        const finishDrag = (e: DragCompleteEvent) => {
+            e.docDragData && (e.docDragData.droppedDocuments =
+                dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
+                    dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) :
+                        dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d)
+            );
+            e.docDragData?.droppedDocuments.forEach((drop: Doc, i: number) =>
+                Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []).map(prop => drop[prop] = undefined));
+        };
         dragData.draggedDocuments.map(d => d.dragFactory); // does this help?  trying to make sure the dragFactory Doc is loaded
-        StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
-            (dropData: { [id: string]: any }) => {
-                (dropData.droppedDocuments =
-                    dragData.draggedDocuments.map(d => !dragData.isSelectionMove && !dragData.userDropAction && ScriptCast(d.onDragStart) ? ScriptCast(d.onDragStart).script.run({ this: d }).result :
-                        dragData.userDropAction === "alias" || (!dragData.userDropAction && dragData.dropAction === "alias") ? Doc.MakeAlias(d) :
-                            dragData.userDropAction === "copy" || (!dragData.userDropAction && dragData.dropAction === "copy") ? Doc.MakeCopy(d, true) : d)
-                );
-                dropData.droppedDocuments.forEach((drop: Doc, i: number) =>
-                    Cast(dragData.draggedDocuments[i].removeDropProperties, listSpec("string"), []).map(prop => drop[prop] = undefined));
-            });
+        StartDrag(eles, dragData, downX, downY, options, finishDrag);
     }
 
+    // drag a button template and drop a new button 
     export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
-        const dragData = new DragManager.DocumentDragData([]);
-        runInAction(() => StartDragFunctions.map(func => func()));
-        StartDrag(eles, dragData, downX, downY, options, options && options.finishDrag ? options.finishDrag :
-            (dropData: { [id: string]: any }) => {
-                const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
-                bd.onClick = ScriptField.MakeScript(script);
-                params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
-                initialize && initialize(bd);
-                bd.buttonParams = new List<string>(params);
-                dropData.droppedDocuments = [bd];
-            });
+        const finishDrag = (e: DragCompleteEvent) => {
+            const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+            bd.onClick = ScriptField.MakeScript(script);
+            params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
+            initialize && initialize(bd);
+            bd.buttonParams = new List<string>(params);
+            e.docDragData && (e.docDragData.droppedDocuments = [bd]);
+        };
+        StartDrag(eles, new DragManager.DocumentDragData([]), downX, downY, options, finishDrag);
     }
 
-    export function StartLinkedDocumentDrag(eles: HTMLElement[], dragData: DocumentDragData, downX: number, downY: number, options?: DragOptions) {
-        dragData.moveDocument = moveLinkedDocument;
+    // drag links and drop link targets (aliasing them if needed)
+    export async function StartLinkTargetsDrag(dragEle: HTMLElement, downX: number, downY: number, sourceDoc: Doc, specificLinks?: Doc[]) {
+        let draggedDocs = (specificLinks ? specificLinks : DocListCast(sourceDoc.links)).map(link => LinkManager.Instance.getOppositeAnchor(link, sourceDoc)).filter(l => l) as Doc[];
 
-        runInAction(() => StartDragFunctions.map(func => func()));
-        StartDrag(eles, dragData, downX, downY, options,
-            (dropData: { [id: string]: any }) => {
-                const droppedDocuments: Doc[] = dragData.draggedDocuments.reduce((droppedDocs: Doc[], d) => {
-                    const dvs = DocumentManager.Instance.getDocumentViews(d);
-                    if (dvs.length) {
-                        const containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
-                        const inContext = dvs.filter(dv => dv.props.ContainingCollectionView === containingView);
-                        if (inContext.length) {
-                            inContext.forEach(dv => droppedDocs.push(dv.props.Document));
+        if (draggedDocs.length) {
+            const moddrag: Doc[] = [];
+            for (const draggedDoc of draggedDocs) {
+                const doc = await Cast(draggedDoc.annotationOn, Doc);
+                if (doc) moddrag.push(doc);
+            }
+
+            let dragData = new DragManager.DocumentDragData(moddrag.length ? moddrag : draggedDocs);
+            dragData.moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean => {
+                const document = SelectionManager.SelectedDocuments()[0];
+                document && document.props.removeDocument && document.props.removeDocument(doc);
+                addDocument(doc);
+                return true;
+            };
+            const containingView = SelectionManager.SelectedDocuments()[0] ? SelectionManager.SelectedDocuments()[0].props.ContainingCollectionView : undefined;
+            const finishDrag = (e: DragCompleteEvent) =>
+                e.docDragData && (e.docDragData.droppedDocuments =
+                    dragData.draggedDocuments.reduce((droppedDocs, d) => {
+                        const dvs = DocumentManager.Instance.getDocumentViews(d).filter(dv => dv.props.ContainingCollectionView === containingView);
+                        if (dvs.length) {
+                            dvs.forEach(dv => droppedDocs.push(dv.props.Document));
                         } else {
                             droppedDocs.push(Doc.MakeAlias(d));
                         }
-                    } else {
-                        droppedDocs.push(Doc.MakeAlias(d));
-                    }
-                    return droppedDocs;
-                }, []);
-                dropData.droppedDocuments = droppedDocuments;
-            });
-    }
-
-    export function StartAnnotationDrag(eles: HTMLElement[], dragData: AnnotationDragData, downX: number, downY: number, options?: DragOptions) {
-        StartDrag(eles, dragData, downX, downY, options);
-    }
+                        return droppedDocs;
+                    }, [] as Doc[]));
 
-    export class LinkDragData {
-        constructor(linkSourceDoc: Doc, blacklist: Doc[] = []) {
-            this.linkSourceDocument = linkSourceDoc;
-            this.blacklist = blacklist;
+            StartDrag([dragEle], dragData, downX, downY, undefined, finishDrag);
         }
-        droppedDocuments: Doc[] = [];
-        linkSourceDocument: Doc;
-        blacklist: Doc[];
-        dontClearTextBox?: boolean;
-        [id: string]: any;
     }
 
-    // for column dragging in schema view
-    export class ColumnDragData {
-        constructor(colKey: SchemaHeaderField) {
-            this.colKey = colKey;
-        }
-        colKey: SchemaHeaderField;
-        [id: string]: any;
+    // drag&drop the pdf annotation anchor which will create a text note  on drop via a dropCompleted() DragOption 
+    export function StartPdfAnnoDrag(eles: HTMLElement[], dragData: PdfAnnoDragData, downX: number, downY: number, options?: DragOptions) {
+        StartDrag(eles, dragData, downX, downY, options);
     }
 
-    export function StartLinkDrag(ele: HTMLElement, dragData: LinkDragData, downX: number, downY: number, options?: DragOptions) {
-        StartDrag([ele], dragData, downX, downY, options);
+    // drags a linker button and creates a link on drop
+    export function StartLinkDrag(ele: HTMLElement, sourceDoc: Doc, downX: number, downY: number, options?: DragOptions) {
+        StartDrag([ele], new DragManager.LinkDragData(sourceDoc), downX, downY, options);
     }
 
+    // drags a column from a schema view
     export function StartColumnDrag(ele: HTMLElement, dragData: ColumnDragData, downX: number, downY: number, options?: DragOptions) {
         StartDrag([ele], dragData, downX, downY, options);
     }
 
-    export let AbortDrag: () => void = emptyFunction;
-
-    function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
+    function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
         eles = eles.filter(e => e);
         if (!dragDiv) {
             dragDiv = document.createElement("div");
@@ -341,33 +278,29 @@ export namespace DragManager {
         const xs: number[] = [];
         const ys: number[] = [];
 
-        const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments :
-            dragData instanceof AnnotationDragData ? [dragData.dragDocument] : [];
+        const docs = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof PdfAnnoDragData ? [dragData.dragDocument] : [];
         const dragElements = eles.map(ele => {
-            const w = ele.offsetWidth,
-                h = ele.offsetHeight;
+            if (!ele.parentNode) dragDiv.appendChild(ele);
+            const dragElement = ele.parentNode === dragDiv ? ele : ele.cloneNode(true) as HTMLElement;
             const rect = ele.getBoundingClientRect();
-            const scaleX = rect.width / w,
-                scaleY = rect.height / h;
-            const x = rect.left,
-                y = rect.top;
-            xs.push(x);
-            ys.push(y);
+            const scaleX = rect.width / ele.offsetWidth,
+                scaleY = rect.height / ele.offsetHeight;
+            xs.push(rect.left);
+            ys.push(rect.top);
             scaleXs.push(scaleX);
             scaleYs.push(scaleY);
-            const dragElement = ele.cloneNode(true) as HTMLElement;
             dragElement.style.opacity = "0.7";
-            dragElement.style.borderRadius = getComputedStyle(ele).borderRadius;
             dragElement.style.position = "absolute";
             dragElement.style.margin = "0";
             dragElement.style.top = "0";
             dragElement.style.bottom = "";
             dragElement.style.left = "0";
-            dragElement.style.transition = "none";
             dragElement.style.color = "black";
+            dragElement.style.transition = "none";
             dragElement.style.transformOrigin = "0 0";
+            dragElement.style.borderRadius = getComputedStyle(ele).borderRadius;
             dragElement.style.zIndex = globalCssVariables.contextMenuZindex;// "1000";
-            dragElement.style.transform = `translate(${x + (options?.offsetX || 0)}px, ${y + (options?.offsetY || 0)}px) scale(${scaleX}, ${scaleY})`;
+            dragElement.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0)}px) scale(${scaleX}, ${scaleY})`;
             dragElement.style.width = `${rect.width / scaleX}px`;
             dragElement.style.height = `${rect.height / scaleY}px`;
 
@@ -385,30 +318,18 @@ export namespace DragManager {
                     Array.from(pdfView).map((v, i) => v.scrollTo({ top: tops[i] }));
                 }, 0);
             }
-            const set = dragElement.getElementsByTagName('*');
             if (dragElement.hasAttribute("style")) (dragElement as any).style.pointerEvents = "none";
+            const set = dragElement.getElementsByTagName('*');
             // tslint:disable-next-line: prefer-for-of
             for (let i = 0; i < set.length; i++) {
-                if (set[i].hasAttribute("style")) {
-                    const s = set[i];
-                    (s as any).style.pointerEvents = "none";
-                }
+                set[i].hasAttribute("style") && ((set[i] as any).style.pointerEvents = "none");
             }
 
-
             dragDiv.appendChild(dragElement);
             return dragElement;
         });
 
-        let hideSource = false;
-        if (options) {
-            if (typeof options.hideSource === "boolean") {
-                hideSource = options.hideSource;
-            } else {
-                hideSource = options.hideSource();
-            }
-        }
-
+        const hideSource = options?.hideSource ? true : false;
         eles.map(ele => ele.parentElement && ele.parentElement?.className === dragData.dragDivName ? (ele.parentElement.hidden = hideSource) : (ele.hidden = hideSource));
 
         let lastX = downX;
@@ -418,9 +339,9 @@ export namespace DragManager {
             if (dragData instanceof DocumentDragData) {
                 dragData.userDropAction = e.ctrlKey ? "alias" : undefined;
             }
-            if (((options && !options.withoutShiftDrag) || !options) && e.shiftKey && CollectionDockingView.Instance) {
+            if (e.shiftKey && CollectionDockingView.Instance) {
                 AbortDrag();
-                finishDrag && finishDrag(dragData);
+                finishDrag?.(new DragCompleteEvent(true, dragData));
                 CollectionDockingView.Instance.StartOtherDrag({
                     pageX: e.pageX,
                     pageY: e.pageY,
@@ -445,45 +366,40 @@ export namespace DragManager {
         const endDrag = () => {
             document.removeEventListener("pointermove", moveHandler, true);
             document.removeEventListener("pointerup", upHandler);
-            if (options) {
-                options.handlers.dragComplete({});
-            }
         };
 
         AbortDrag = () => {
             hideDragShowOriginalElements();
             SelectionManager.SetIsDragging(false);
+            options?.dragComplete?.(new DragCompleteEvent(true, dragData));
             endDrag();
         };
         const upHandler = (e: PointerEvent) => {
             hideDragShowOriginalElements();
             dispatchDrag(eles, e, dragData, options, finishDrag);
             SelectionManager.SetIsDragging(false);
+            options?.dragComplete?.(new DragCompleteEvent(false, dragData));
             endDrag();
         };
         document.addEventListener("pointermove", moveHandler, true);
         document.addEventListener("pointerup", upHandler);
     }
 
-    function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
+    function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (e: DragCompleteEvent) => void) {
         const removed = dragData.dontHideOnDrop ? [] : dragEles.map(dragEle => {
-            // let parent = dragEle.parentElement;
-            // if (parent) parent.removeChild(dragEle);
-            const ret = [dragEle, dragEle.style.width, dragEle.style.height];
+            const ret = { ele: dragEle, w: dragEle.style.width, h: dragEle.style.height };
             dragEle.style.width = "0";
             dragEle.style.height = "0";
             return ret;
         });
         const target = document.elementFromPoint(e.x, e.y);
         removed.map(r => {
-            const dragEle = r[0] as HTMLElement;
-            dragEle.style.width = r[1] as string;
-            dragEle.style.height = r[2] as string;
-            // let parent = r[1];
-            // if (parent && dragEle) parent.appendChild(dragEle);
+            r.ele.style.width = r.w;
+            r.ele.style.height = r.h;
         });
         if (target) {
-            finishDrag && finishDrag(dragData);
+            const complete = new DragCompleteEvent(false, dragData);
+            finishDrag?.(complete);
 
             target.dispatchEvent(
                 new CustomEvent<DropEvent>("dashOnDrop", {
@@ -491,8 +407,10 @@ export namespace DragManager {
                     detail: {
                         x: e.x,
                         y: e.y,
-                        data: dragData,
-                        mods: e.altKey ? "AltKey" : e.ctrlKey ? "CtrlKey" : e.metaKey ? "MetaKey" : ""
+                        complete: complete,
+                        altKey: e.altKey,
+                        metaKey: e.metaKey,
+                        ctrlKey: e.ctrlKey
                     }
                 })
             );
diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts
index fb6f27478..5f3667acc 100644
--- a/src/client/util/LinkManager.ts
+++ b/src/client/util/LinkManager.ts
@@ -70,7 +70,7 @@ export class LinkManager {
     }
 
     // finds all links that contain the given anchor
-    public getAllRelatedLinks(anchor: Doc): Doc[] {//List<Doc> {
+    public getAllRelatedLinks(anchor: Doc): Doc[] {
         const related = LinkManager.Instance.getAllLinks().filter(link => {
             const protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null));
             const protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null));
@@ -244,7 +244,5 @@ export class LinkManager {
         if (Doc.AreProtosEqual(anchor, linkDoc)) return linkDoc;
     }
 }
-Scripting.addGlobal(function links(doc: any) {
-    return new List(LinkManager.Instance.getAllRelatedLinks(doc));
-});
 
+Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); });
\ No newline at end of file
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index 293a4feea..5ca861f71 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -39,7 +39,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
     protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
         this._dropDisposer && this._dropDisposer();
         if (ele) {
-            this._dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+            this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
         }
     }
 
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 27ee9f122..c7ddee7ea 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -71,7 +71,7 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         // if the moved document is already in this overlay collection nothing needs to be done.
         // otherwise, if the document can be removed from where it was, it will then be added to this document's overlay collection. 
         @action.bound
-        moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
+        moveDocument(doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean {
             return Doc.AreProtosEqual(this.props.Document, targetCollection) ? true : this.removeDocument(doc) ? addDocument(doc) : false;
         }
         @action.bound
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 7f125dd34..f014c1329 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -3,13 +3,12 @@ import { faArrowAltCircleDown, faArrowAltCircleUp, faCheckCircle, faCloudUploadA
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, observable, runInAction, computed } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../new_fields/Doc";
+import { Doc, DocListCast } from "../../new_fields/Doc";
 import { RichTextField } from '../../new_fields/RichTextField';
-import { NumCast, StrCast } from "../../new_fields/Types";
+import { NumCast, StrCast, Cast } from "../../new_fields/Types";
 import { emptyFunction } from "../../Utils";
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { DragManager } from "../util/DragManager";
-import { LinkManager } from '../util/LinkManager';
 import { UndoManager } from "../util/UndoManager";
 import './DocumentButtonBar.scss';
 import './collections/ParentDocumentSelector.scss';
@@ -107,27 +106,21 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
         if (this._linkButton.current !== null && (Math.abs(e.clientX - this._downX) > 3 || Math.abs(e.clientY - this._downY) > 3)) {
             document.removeEventListener("pointermove", this.onLinkButtonMoved);
             document.removeEventListener("pointerup", this.onLinkButtonUp);
-            const docView = this.props.views[0];
-            const container = docView.props.ContainingCollectionDoc?.proto;
-            const dragData = new DragManager.LinkDragData(docView.props.Document, container ? [container] : []);
             const linkDrag = UndoManager.StartBatch("Drag Link");
-            DragManager.StartLinkDrag(this._linkButton.current, dragData, e.pageX, e.pageY, {
-                handlers: {
-                    dragComplete: () => {
-                        const tooltipmenu = FormattedTextBox.ToolTipTextMenu;
-                        const linkDoc = dragData.linkDocument;
-                        if (linkDoc && tooltipmenu) {
-                            const proto = Doc.GetProto(linkDoc);
-                            if (proto && docView) {
-                                proto.sourceContext = docView.props.ContainingCollectionDoc;
-                            }
-                            const text = tooltipmenu.makeLink(linkDoc, StrCast(linkDoc.anchor2.title), e.ctrlKey ? "onRight" : "inTab");
-                            if (linkDoc instanceof Doc && linkDoc.anchor2 instanceof Doc) {
-                                proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODODO open to more descriptive descriptions of following in text link
-                            }
+            DragManager.StartLinkDrag(this._linkButton.current, this.props.views[0].props.Document, e.pageX, e.pageY, {
+                dragComplete: dropEv => {
+                    const linkDoc = dropEv.linkDragData?.linkDocument; // equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop
+                    if (linkDoc && FormattedTextBox.ToolTipTextMenu) {
+                        const proto = Doc.GetProto(linkDoc);
+                        proto.sourceContext = this.props.views[0].props.ContainingCollectionDoc;
+
+                        const anchor2Title = linkDoc.anchor2 instanceof Doc ? StrCast((linkDoc.anchor2 as Doc).title) : "-untitled-";
+                        const text = FormattedTextBox.ToolTipTextMenu.makeLink(linkDoc, anchor2Title, e.ctrlKey ? "onRight" : "inTab");
+                        if (linkDoc.anchor2 instanceof Doc) {
+                            proto.title = text === "" ? proto.title : text + " to " + linkDoc.anchor2.title; // TODO open to more descriptive descriptions of following in text link
                         }
-                        linkDrag && linkDrag.end();
                     }
+                    linkDrag?.end();
                 },
                 hideSource: false
             });
@@ -200,7 +193,7 @@ export class DocumentButtonBar extends React.Component<{ views: DocumentView[],
 
     @computed
     get linkButton() {
-        const linkCount = LinkManager.Instance.getAllRelatedLinks(this.props.views[0].props.Document).length;
+        const linkCount = DocListCast(this.props.views[0].props.Document.links).length;
         return <div title="Drag(create link) Tap(view links)" className="documentButtonBar-linkFlyout" ref={this._linkButton}>
             <Flyout anchorPoint={anchorPoints.RIGHT_TOP}
                 content={<LinkMenu docView={this.props.views[0]} addDocTab={this.props.views[0].props.addDocTab} changeFlyout={emptyFunction} />}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index f366a3677..fdaca87a9 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -199,7 +199,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         document.removeEventListener("pointermove", this.onTitleMove);
         document.removeEventListener("pointerup", this.onTitleUp);
         DragManager.StartDocumentDrag(SelectionManager.SelectedDocuments().map(documentView => documentView.ContentDiv!), dragData, e.x, e.y, {
-            handlers: { dragComplete: action(() => this._hidden = this.Interacting = false) },
+            dragComplete: action(e => this._hidden = this.Interacting = false),
             hideSource: true
         });
         e.stopPropagation();
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 25b7dc5ec..db2a3c298 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -460,7 +460,7 @@ export class MainView extends React.Component {
 
     addButtonDoc = (doc: Doc) => Doc.AddDocToList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc);
     remButtonDoc = (doc: Doc) => Doc.RemoveDocFromList(CurrentUserUtils.UserDocument.expandingButtons as Doc, "data", doc);
-    moveButtonDoc = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
+    moveButtonDoc = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => this.remButtonDoc(doc) && addDocument(doc);
 
     buttonBarXf = () => {
         if (!this._docBtnRef.current) return Transform.Identity();
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index cd330d492..350a75d29 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -9,8 +9,6 @@ import { DocListCast, Doc } from "../../new_fields/Doc";
 import { Id } from "../../new_fields/FieldSymbols";
 import { DocumentView } from "./nodes/DocumentView";
 import { Transform } from "../util/Transform";
-import { CollectionFreeFormDocumentView } from "./nodes/CollectionFreeFormDocumentView";
-import { DocumentContentsView } from "./nodes/DocumentContentsView";
 import { NumCast } from "../../new_fields/Types";
 import { CollectionFreeFormLinksView } from "./collections/collectionFreeForm/CollectionFreeFormLinksView";
 
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 8d9dc4cf7..f7cfc4022 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -66,7 +66,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         const ex = e.target.getBoundingClientRect().left;
         const ey = e.target.getBoundingClientRect().top;
         const de = new DragManager.DocumentDragData([topDoc]);
-        de.dragDivName =  topDocView.props.dragDivName;
+        de.dragDivName = topDocView.props.dragDivName;
         de.moveDocument = topDocView.props.moveDocument;
         undoBatch(action(() => topDoc.z = topDoc.z ? 0 : 1))();
         setTimeout(() => {
@@ -74,11 +74,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
             if (newDocView) {
                 const contentDiv = newDocView.ContentDiv!;
                 const xf = contentDiv.getBoundingClientRect();
-                DragManager.StartDocumentDrag([contentDiv], de, ex, ey, {
-                    offsetX: ex - xf.left, offsetY: ey - xf.top,
-                    handlers: { dragComplete: () => { }, },
-                    hideSource: true
-                });
+                DragManager.StartDocumentDrag([contentDiv], de, ex, ey, { offsetX: ex - xf.left, offsetY: ey - xf.top, hideSource: true });
             }
         }, 0);
     }
@@ -148,9 +144,6 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
             DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, {
                 offsetX: dragData.offset[0],
                 offsetY: dragData.offset[1],
-                handlers: {
-                    dragComplete: action(emptyFunction),
-                },
                 hideSource: false
             });
         }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index ffcb3e9ce..08b9fd216 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -20,7 +20,7 @@ import { emptyFunction, returnEmptyString, returnFalse, returnOne, returnTrue, U
 import { DocServer } from "../../DocServer";
 import { Docs } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
-import { DragLinksAsDocuments, DragManager } from "../../util/DragManager";
+import { DragManager } from "../../util/DragManager";
 import { SelectionManager } from '../../util/SelectionManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch } from "../../util/UndoManager";
@@ -346,7 +346,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             const docid = (e.target as any).DashDocId;
             const tab = (e.target as any).parentElement as HTMLElement;
             DocServer.GetRefField(docid).then(action(async (sourceDoc: Opt<Field>) =>
-                (sourceDoc instanceof Doc) && DragLinksAsDocuments(tab, x, y, sourceDoc)));
+                (sourceDoc instanceof Doc) && DragManager.StartLinkTargetsDrag(tab, x, y, sourceDoc)));
         }
         if (className === "lm_drag_handle" || className === "lm_close" || className === "lm_maximise" || className === "lm_minimise" || className === "lm_close_tab") {
             this._flush = true;
@@ -419,15 +419,13 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
                 };
                 ReactDOM.render(<span title="Drag as document"
                     className="collectionDockingView-dragAsDocument"
-                    onPointerDown={
-                        e => {
-                            e.preventDefault();
-                            e.stopPropagation();
-                            DragManager.StartDocumentDrag([dragSpan], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY, {
-                                handlers: { dragComplete: emptyFunction },
-                                hideSource: false
-                            });
-                        }}><FontAwesomeIcon icon="file" size="lg" /></span>, dragSpan);
+                    onPointerDown={e => {
+                        e.preventDefault();
+                        e.stopPropagation();
+                        DragManager.StartDocumentDrag([dragSpan], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY);
+                    }}>
+                    <FontAwesomeIcon icon="file" size="lg" />
+                </span>, dragSpan);
                 ReactDOM.render(<ButtonSelector Document={doc} Stack={stack} />, gearSpan);
                 tab.reactComponents = [dragSpan, gearSpan, upDiv];
                 tab.element.append(dragSpan);
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index d697e721b..80752303c 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -56,7 +56,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     createRowDropRef = (ele: HTMLDivElement | null) => {
         this._dropDisposer && this._dropDisposer();
         if (ele) {
-            this._dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
+            this._dropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this));
         }
     }
 
@@ -74,12 +74,12 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @undoBatch
     rowDrop = action((e: Event, de: DragManager.DropEvent) => {
         this._createAliasSelected = false;
-        if (de.data instanceof DragManager.DocumentDragData) {
+        if (de.complete.docDragData) {
             (this.props.parent.Document.dropConverter instanceof ScriptField) &&
-                this.props.parent.Document.dropConverter.script.run({ dragData: de.data });
+                this.props.parent.Document.dropConverter.script.run({ dragData: de.complete.docDragData });
             const key = StrCast(this.props.parent.props.Document.sectionFilter);
             const castedValue = this.getValue(this._heading);
-            de.data.droppedDocuments.forEach(d => d[key] = castedValue);
+            de.complete.docDragData.droppedDocuments.forEach(d => d[key] = castedValue);
             this.props.parent.drop(e, de);
             e.stopPropagation();
         }
@@ -171,10 +171,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             const script = `return doc.${key} === ${value}`;
             const compiled = CompileScript(script, { params: { doc: Doc.name } });
             if (compiled.compiled) {
-                const scriptField = new ScriptField(compiled);
-                alias.viewSpecScript = scriptField;
-                const dragData = new DragManager.DocumentDragData([alias]);
-                DragManager.StartDocumentDrag([this._headerRef.current!], dragData, e.clientX, e.clientY);
+                alias.viewSpecScript = new ScriptField(compiled);
+                DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY);
             }
 
             e.stopPropagation();
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 171dc4606..79a34bc00 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -37,7 +37,7 @@ export interface CellProps {
     renderDepth: number;
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
     pinToPres: (document: Doc) => void;
-    moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     isFocused: boolean;
     changeFocusedCellByIndex: (row: number, col: number) => void;
     setIsEditing: (isEditing: boolean) => void;
@@ -105,13 +105,13 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     }
 
     private drop = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
+        if (de.complete.docDragData) {
             const fieldKey = this.props.rowProps.column.id as string;
-            if (de.data.draggedDocuments.length === 1) {
-                this._document[fieldKey] = de.data.draggedDocuments[0];
+            if (de.complete.docDragData.draggedDocuments.length === 1) {
+                this._document[fieldKey] = de.complete.docDragData.draggedDocuments[0];
             }
             else {
-                const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.data.draggedDocuments, {});
+                const coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.complete.docDragData.draggedDocuments, {});
                 this._document[fieldKey] = coll;
             }
             e.stopPropagation();
@@ -121,7 +121,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
     private dropRef = (ele: HTMLElement | null) => {
         this._dropDisposer && this._dropDisposer();
         if (ele) {
-            this._dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+            this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
         }
     }
 
@@ -167,11 +167,10 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
 
         const onItemDown = (e: React.PointerEvent) => {
-            if (fieldIsDoc) {
-                SetupDrag(this._focusRef, () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
-                    this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument,
-                    this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
-            }
+            fieldIsDoc && SetupDrag(this._focusRef,
+                () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
+                this._document[props.fieldKey] instanceof Doc ? (doc: Doc, target: Doc | undefined, addDoc: (newDoc: Doc) => any) => addDoc(doc) : this.props.moveDocument,
+                this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
         };
         const onPointerEnter = (e: React.PointerEvent): void => {
             if (e.buttons === 1 && SelectionManager.GetIsDragging() && (type === "document" || type === undefined)) {
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 90320df82..153bbd410 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -56,7 +56,7 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
     createColDropTarget = (ele: HTMLDivElement) => {
         this._colDropDisposer && this._colDropDisposer();
         if (ele) {
-            this._colDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.colDrop.bind(this) } });
+            this._colDropDisposer = DragManager.MakeDropTarget(ele, this.colDrop.bind(this));
         }
     }
 
@@ -66,8 +66,8 @@ export class MovableColumn extends React.Component<MovableColumnProps> {
         const rect = this._header!.current!.getBoundingClientRect();
         const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left + ((rect.right - rect.left) / 2), rect.top);
         const before = x[0] < bounds[0];
-        if (de.data instanceof DragManager.ColumnDragData) {
-            this.props.reorderColumns(de.data.colKey, this.props.columnValue, before, this.props.allColumns);
+        if (de.complete.columnDragData) {
+            this.props.reorderColumns(de.complete.columnDragData.colKey, this.props.columnValue, before, this.props.allColumns);
             return true;
         }
         return false;
@@ -165,7 +165,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
     createRowDropTarget = (ele: HTMLDivElement) => {
         this._rowDropDisposer && this._rowDropDisposer();
         if (ele) {
-            this._rowDropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
+            this._rowDropDisposer = DragManager.MakeDropTarget(ele, this.rowDrop.bind(this));
         }
     }
 
@@ -178,16 +178,17 @@ export class MovableRow extends React.Component<MovableRowProps> {
         const bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
         const before = x[1] < bounds[1];
 
-        if (de.data instanceof DragManager.DocumentDragData) {
+        const docDragData = de.complete.docDragData;
+        if (docDragData) {
             e.stopPropagation();
-            if (de.data.draggedDocuments[0] === rowDoc) return true;
+            if (docDragData.draggedDocuments[0] === rowDoc) return true;
             const addDocument = (doc: Doc) => this.props.addDoc(doc, rowDoc, before);
-            const movedDocs = de.data.draggedDocuments;
-            return (de.data.dropAction || de.data.userDropAction) ?
-                de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false)
-                : (de.data.moveDocument) ?
-                    movedDocs.reduce((added: boolean, d) => de.data.moveDocument(d, rowDoc, addDocument) || added, false)
-                    : de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
+            const movedDocs = docDragData.draggedDocuments;
+            return (docDragData.dropAction || docDragData.userDropAction) ?
+                docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before) || added, false)
+                : (docDragData.moveDocument) ?
+                    movedDocs.reduce((added: boolean, d) => docDragData.moveDocument?.(d, rowDoc, addDocument) || added, false)
+                    : docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDoc(d, rowDoc, before), false);
         }
         return false;
     }
@@ -199,12 +200,12 @@ export class MovableRow extends React.Component<MovableRowProps> {
 
     @undoBatch
     @action
-    move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
-        const targetView = DocumentManager.Instance.getDocumentView(target);
+    move: DragManager.MoveFunction = (doc: Doc, targetCollection: Doc | undefined, addDoc) => {
+        const targetView = targetCollection && DocumentManager.Instance.getDocumentView(targetCollection);
         if (targetView && targetView.props.ContainingCollectionDoc) {
-            return doc !== target && doc !== targetView.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc);
+            return doc !== targetCollection && doc !== targetView.props.ContainingCollectionDoc && this.props.removeDoc(doc) && addDoc(doc);
         }
-        return doc !== target && this.props.removeDoc(doc) && addDoc(doc);
+        return doc !== targetCollection && this.props.removeDoc(doc) && addDoc(doc);
     }
 
     render() {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 8169e9e2b..bb706e528 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -224,7 +224,7 @@ export interface SchemaTableProps {
     renderDepth: number;
     deleteDocument: (document: Doc) => boolean;
     addDocument: (document: Doc) => boolean;
-    moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     active: (outsideReaction: boolean) => boolean;
     onDrop: (e: React.DragEvent<Element>, options: DocumentOptions, completed?: (() => void) | undefined) => void;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ff3417b77..6a23920f3 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -147,7 +147,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
 
     @action
-    moveDocument = (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean): boolean => {
+    moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean): boolean => {
         return this.props.removeDocument(doc) && addDocument(doc);
     }
     createRef = (ele: HTMLDivElement | null) => {
@@ -243,7 +243,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         const where = [de.x, de.y];
         let targInd = -1;
         let plusOne = false;
-        if (de.data instanceof DragManager.DocumentDragData) {
+        if (de.complete.docDragData) {
             this._docXfs.map((cd, i) => {
                 const pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
                 const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
@@ -252,16 +252,16 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     plusOne = (where[1] > (pos[1] + pos1[1]) / 2 ? 1 : 0) ? true : false;
                 }
             });
-        }
-        if (super.drop(e, de)) {
-            const newDoc = de.data.droppedDocuments[0];
-            const docs = this.childDocList;
-            if (docs) {
-                if (targInd === -1) targInd = docs.length;
-                else targInd = docs.indexOf(this.filteredChildren[targInd]);
-                const srcInd = docs.indexOf(newDoc);
-                docs.splice(srcInd, 1);
-                docs.splice((targInd > srcInd ? targInd - 1 : targInd) + (plusOne ? 1 : 0), 0, newDoc);
+            if (super.drop(e, de)) {
+                const newDoc = de.complete.docDragData.droppedDocuments[0];
+                const docs = this.childDocList;
+                if (docs) {
+                    if (targInd === -1) targInd = docs.length;
+                    else targInd = docs.indexOf(this.filteredChildren[targInd]);
+                    const srcInd = docs.indexOf(newDoc);
+                    docs.splice(srcInd, 1);
+                    docs.splice((targInd > srcInd ? targInd - 1 : targInd) + (plusOne ? 1 : 0), 0, newDoc);
+                }
             }
         }
         return false;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index ca3b93bf8..39b4e4e1d 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -51,21 +51,21 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         this._dropRef = ele;
         this.dropDisposer && this.dropDisposer();
         if (ele) {
-            this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.columnDrop.bind(this) } });
+            this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
         }
     }
 
     @undoBatch
     columnDrop = action((e: Event, de: DragManager.DropEvent) => {
         this._createAliasSelected = false;
-        if (de.data instanceof DragManager.DocumentDragData) {
+        if (de.complete.docDragData) {
             const key = StrCast(this.props.parent.props.Document.sectionFilter);
             const castedValue = this.getValue(this._heading);
             if (castedValue) {
-                de.data.droppedDocuments.forEach(d => d[key] = castedValue);
+                de.complete.docDragData.droppedDocuments.forEach(d => d[key] = castedValue);
             }
             else {
-                de.data.droppedDocuments.forEach(d => d[key] = undefined);
+                de.complete.docDragData.droppedDocuments.forEach(d => d[key] = undefined);
             }
             this.props.parent.drop(e, de);
             e.stopPropagation();
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 9fa244546..5c7794cc0 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -27,7 +27,7 @@ import { Networking } from "../../Network";
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc) => boolean;
     removeDocument: (document: Doc) => boolean;
-    moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     PanelWidth: () => number;
     PanelHeight: () => number;
     VisibleHeight?: () => number;
@@ -51,7 +51,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
             this.dropDisposer && this.dropDisposer();
             if (ele) {
-                this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+                this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
             }
         }
         protected CreateDropTarget(ele: HTMLDivElement) { //used in schema view
@@ -132,32 +132,33 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         @undoBatch
         @action
         protected drop(e: Event, de: DragManager.DropEvent): boolean {
+            const docDragData = de.complete.docDragData;
             (this.props.Document.dropConverter instanceof ScriptField) &&
-                this.props.Document.dropConverter.script.run({ dragData: de.data });
-            if (de.data instanceof DragManager.DocumentDragData && !de.data.applyAsTemplate) {
-                if (de.mods === "AltKey" && de.data.draggedDocuments.length) {
+                this.props.Document.dropConverter.script.run({ dragData: docDragData }); /// bcz: check this 
+            if (docDragData && !docDragData.applyAsTemplate) {
+                if (de.altKey && docDragData.draggedDocuments.length) {
                     this.childDocs.map(doc =>
-                        Doc.ApplyTemplateTo(de.data.draggedDocuments[0], doc, "layoutFromParent"));
+                        Doc.ApplyTemplateTo(docDragData.draggedDocuments[0], doc, "layoutFromParent"));
                     e.stopPropagation();
                     return true;
                 }
                 let added = false;
-                if (de.data.dropAction || de.data.userDropAction) {
-                    added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
-                } else if (de.data.moveDocument) {
-                    const movedDocs = de.data.draggedDocuments;
+                if (docDragData.dropAction || docDragData.userDropAction) {
+                    added = docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
+                } else if (docDragData.moveDocument) {
+                    const movedDocs = docDragData.draggedDocuments;
                     added = movedDocs.reduce((added: boolean, d, i) =>
-                        de.data.droppedDocuments[i] !== d ? this.props.addDocument(de.data.droppedDocuments[i]) :
-                            de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false);
+                        docDragData.droppedDocuments[i] !== d ? this.props.addDocument(docDragData.droppedDocuments[i]) :
+                            docDragData.moveDocument?.(d, this.props.Document, this.props.addDocument) || added, false);
                 } else {
-                    added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
+                    added = docDragData.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
                 }
                 e.stopPropagation();
                 return added;
             }
-            else if (de.data instanceof DragManager.AnnotationDragData) {
+            else if (de.complete.annoDragData) {
                 e.stopPropagation();
-                return this.props.addDocument(de.data.dropDocument);
+                return this.props.addDocument(de.complete.annoDragData.dropDocument);
             }
             return false;
         }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ec1e7409f..0a22a897c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -123,7 +123,7 @@ class TreeView extends React.Component<TreeViewProps> {
     @undoBatch delete = () => this.props.deleteDoc(this.props.document);
     @undoBatch openRight = () => this.props.addDocTab(this.props.document, this.templateDataDoc, "onRight", this.props.libraryPath);
     @undoBatch indent = () => this.props.addDocument(this.props.document) && this.delete();
-    @undoBatch move = (doc: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => {
+    @undoBatch move = (doc: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => {
         return this.props.document !== target && this.props.deleteDoc(doc) && addDoc(doc);
     }
     @undoBatch @action remove = (document: Document, key: string) => {
@@ -132,7 +132,7 @@ class TreeView extends React.Component<TreeViewProps> {
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
         this._treedropDisposer && this._treedropDisposer();
-        ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.treeDrop.bind(this) } }));
+        ele && (this._treedropDisposer = DragManager.MakeDropTarget(ele, this.treeDrop.bind(this)));
     }
 
     onPointerDown = (e: React.PointerEvent) => e.stopPropagation();
@@ -220,25 +220,25 @@ class TreeView extends React.Component<TreeViewProps> {
         const rect = this._header!.current!.getBoundingClientRect();
         const before = pt[1] < rect.top + rect.height / 2;
         const inside = pt[0] > Math.min(rect.left + 75, rect.left + rect.width * .75) || (!before && this.treeViewOpen && DocListCast(this.dataDoc[this.fieldKey]).length);
-        if (de.data instanceof DragManager.LinkDragData) {
-            const sourceDoc = de.data.linkSourceDocument;
+        if (de.complete.linkDragData) {
+            const sourceDoc = de.complete.linkDragData.linkSourceDocument;
             const destDoc = this.props.document;
             DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc });
             e.stopPropagation();
         }
-        if (de.data instanceof DragManager.DocumentDragData) {
+        if (de.complete.docDragData) {
             e.stopPropagation();
-            if (de.data.draggedDocuments[0] === this.props.document) return true;
+            if (de.complete.docDragData.draggedDocuments[0] === this.props.document) return true;
             let addDoc = (doc: Doc) => this.props.addDocument(doc, undefined, before);
             if (inside) {
                 addDoc = (doc: Doc) => Doc.AddDocToList(this.dataDoc, this.fieldKey, doc) || addDoc(doc);
             }
-            const movedDocs = (de.data.options === this.props.treeViewId ? de.data.draggedDocuments : de.data.droppedDocuments);
-            return ((de.data.dropAction && (de.data.options !== this.props.treeViewId)) || de.data.userDropAction) ?
-                de.data.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
-                : de.data.moveDocument ?
-                    movedDocs.reduce((added, d) => de.data.moveDocument(d, undefined, addDoc) || added, false)
-                    : de.data.droppedDocuments.reduce((added, d) => addDoc(d), false);
+            const movedDocs = (de.complete.docDragData.treeViewId === this.props.treeViewId ? de.complete.docDragData.draggedDocuments : de.complete.docDragData.droppedDocuments);
+            return ((de.complete.docDragData.dropAction && (de.complete.docDragData.treeViewId !== this.props.treeViewId)) || de.complete.docDragData.userDropAction) ?
+                de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d) || added, false)
+                : de.complete.docDragData.moveDocument ?
+                    movedDocs.reduce((added, d) => de.complete.docDragData?.moveDocument?.(d, undefined, addDoc) || added, false)
+                    : de.complete.docDragData.droppedDocuments.reduce((added, d) => addDoc(d), false);
         }
         return false;
     }
@@ -571,7 +571,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
         this.treedropDisposer && this.treedropDisposer();
         if (this._mainEle = ele) {
-            this.treedropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+            this.treedropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
         }
     }
 
@@ -624,7 +624,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     render() {
         const dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
         const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
-        const moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
+        const moveDoc = (d: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
         return !this.childDocs ? (null) : (
             <div className="collectionTreeView-dropTarget" id="body"
                 style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 15eec37de..9bd07966c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -68,7 +68,7 @@ export namespace CollectionViewType {
 export interface CollectionRenderProps {
     addDocument: (document: Doc) => boolean;
     removeDocument: (document: Doc) => boolean;
-    moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     active: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
 }
@@ -150,7 +150,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     // otherwise, the document being moved must be able to be removed from its container before
     // moving it into the target.  
     @action.bound
-    moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
+    moveDocument(doc: Doc, targetCollection: Doc | undefined, addDocument: (doc: Doc) => boolean): boolean {
         if (Doc.AreProtosEqual(this.props.Document, targetCollection)) {
             return true;
         }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 4161e5d6e..a870b6043 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -288,15 +288,15 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     protected createDropTarget = (ele: HTMLDivElement) => {
         this.dropDisposer && this.dropDisposer();
         if (ele) {
-            this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+            this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
         }
     }
 
     @undoBatch
     @action
     protected drop(e: Event, de: DragManager.DropEvent): boolean {
-        if (de.data instanceof DragManager.DocumentDragData && de.data.draggedDocuments.length) {
-            this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.data.draggedDocuments));
+        if (de.complete.docDragData && de.complete.docDragData.draggedDocuments.length) {
+            this._buttonizableCommands.filter(c => c.title === this._currentKey).map(c => c.immediate(de.complete.docDragData?.draggedDocuments || []));
             e.stopPropagation();
         }
         return true;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index ddfb52ba9..89c1df598 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -139,15 +139,15 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         const [xp, yp] = xf.transformPoint(de.x, de.y);
         const [xpo, ypo] = xfo.transformPoint(de.x, de.y);
         if (super.drop(e, de)) {
-            if (de.data instanceof DragManager.DocumentDragData) {
-                if (de.data.droppedDocuments.length) {
-                    const firstDoc = de.data.droppedDocuments[0];
+            if (de.complete.docDragData) {
+                if (de.complete.docDragData.droppedDocuments.length) {
+                    const firstDoc = de.complete.docDragData.droppedDocuments[0];
                     const z = NumCast(firstDoc.z);
-                    const x = (z ? xpo : xp) - de.data.offset[0];
-                    const y = (z ? ypo : yp) - de.data.offset[1];
+                    const x = (z ? xpo : xp) - de.complete.docDragData.offset[0];
+                    const y = (z ? ypo : yp) - de.complete.docDragData.offset[1];
                     const dropX = NumCast(firstDoc.x);
                     const dropY = NumCast(firstDoc.y);
-                    de.data.droppedDocuments.forEach(action((d: Doc) => {
+                    de.complete.docDragData.droppedDocuments.forEach(action((d: Doc) => {
                         const layoutDoc = Doc.Layout(d);
                         d.x = x + NumCast(d.x) - dropX;
                         d.y = y + NumCast(d.y) - dropY;
@@ -162,19 +162,19 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                         this.bringToFront(d);
                     }));
 
-                    de.data.droppedDocuments.length === 1 && this.updateCluster(de.data.droppedDocuments[0]);
+                    de.complete.docDragData.droppedDocuments.length === 1 && this.updateCluster(de.complete.docDragData.droppedDocuments[0]);
                 }
             }
-            else if (de.data instanceof DragManager.AnnotationDragData) {
-                if (de.data.dropDocument) {
-                    const dragDoc = de.data.dropDocument;
-                    const x = xp - de.data.offset[0];
-                    const y = yp - de.data.offset[1];
+            else if (de.complete.annoDragData) {
+                if (de.complete.annoDragData.dropDocument) {
+                    const dragDoc = de.complete.annoDragData.dropDocument;
+                    const x = xp - de.complete.annoDragData.offset[0];
+                    const y = yp - de.complete.annoDragData.offset[1];
                     const dropX = NumCast(dragDoc.x);
                     const dropY = NumCast(dragDoc.y);
                     dragDoc.x = x + NumCast(dragDoc.x) - dropX;
                     dragDoc.y = y + NumCast(dragDoc.y) - dropY;
-                    de.data.targetContext = this.props.Document; // dropped a PDF annotation, so we need to set the targetContext on the dragData which the PDF view uses at the end of the drop operation
+                    de.complete.annoDragData.targetContext = this.props.Document; // dropped a PDF annotation, so we need to set the targetContext on the dragData which the PDF view uses at the end of the drop operation
                     this.bringToFront(dragDoc);
                 }
             }
@@ -205,10 +205,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 const [left, top] = clusterDocs[0].props.ScreenToLocalTransform().scale(clusterDocs[0].props.ContentScaling()).inverse().transformPoint(0, 0);
                 de.offset = this.getTransform().transformDirection(ptsParent.clientX - left, ptsParent.clientY - top);
                 de.dropAction = e.ctrlKey || e.altKey ? "alias" : undefined;
-                DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, ptsParent.clientX, ptsParent.clientY, {
-                    handlers: { dragComplete: action(emptyFunction) },
-                    hideSource: !de.dropAction
-                });
+                DragManager.StartDocumentDrag(clusterDocs.map(v => v.ContentDiv!), de, ptsParent.clientX, ptsParent.clientY, { hideSource: !de.dropAction });
                 return true;
             }
         }
@@ -896,7 +893,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // otherwise, they are stored in fieldKey.  All annotations to this document are stored in the extension document
         return !this.extensionDoc ? (null) :
             <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
-                style={{ height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
+                style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
                 onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
                 <MarqueeView {...this.props} extensionDoc={this.extensionDoc} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
                     addLiveTextDocument={this.addLiveTextBox} getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
diff --git a/src/client/views/linking/LinkMenu.scss b/src/client/views/linking/LinkMenu.scss
index a4018bd2d..7dee22f66 100644
--- a/src/client/views/linking/LinkMenu.scss
+++ b/src/client/views/linking/LinkMenu.scss
@@ -48,90 +48,5 @@
     }
 }
 
-.linkMenu-item {
-    // border-top: 0.5px solid $main-accent; 
-    position: relative;
-    display: flex;
-    font-size: 12px;
-    
-
-    .link-name {
-        position: relative;
-
-        p {
-            padding: 4px 6px;
-            line-height: 12px;
-            border-radius: 5px;
-            overflow-wrap: break-word;
-        }
-    }
-
-    .linkMenu-item-content {
-        width: 100%;
-    }
-    
-    .link-metadata {
-        padding: 0 10px 0 16px;
-        margin-bottom: 4px;
-        color: $main-accent;
-        font-style: italic;
-        font-size: 10.5px;
-    }
-
-    &:hover {
-        .linkMenu-item-buttons {
-            display: flex;
-        }
-        .linkMenu-item-content {
-            &.expand-two p {
-                width: calc(100% - 52px);
-                background-color: lightgray;
-            }
-            &.expand-three p {
-                width: calc(100% - 84px);
-                background-color: lightgray;
-            }
-        }
-    }
-}
-
-.linkMenu-item-buttons {
-    display: none;
-    position: absolute;
-    top: 50%;
-    right: 0;
-    transform: translateY(-50%);
-
-    .button {
-        width: 20px;
-        height: 20px;
-        margin: 0;
-        margin-right: 6px;
-        border-radius: 50%;
-        cursor: pointer;
-        pointer-events: auto;
-        background-color: $dark-color;
-        color: $light-color;
-        font-size: 65%;
-        transition: transform 0.2s;
-        text-align: center;
-        position: relative;
-
-        .fa-icon {
-            position: absolute;
-            top: 50%;
-            left: 50%;
-            transform: translate(-50%, -50%);
-        }
-
-        &:last-child {
-            margin-right: 0;
-        }
-        &:hover {
-            background: $main-accent;
-        }
-    }
-}
-
 
 
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index 15aacbbc9..da56435f2 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -4,11 +4,9 @@ import { observer } from "mobx-react";
 import { Doc } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
-import { emptyFunction } from "../../../Utils";
 import { Docs } from "../../documents/Documents";
 import { DragManager, SetupDrag } from "../../util/DragManager";
 import { LinkManager } from "../../util/LinkManager";
-import { UndoManager } from "../../util/UndoManager";
 import { DocumentView } from "../nodes/DocumentView";
 import './LinkMenu.scss';
 import { LinkMenuItem } from "./LinkMenuItem";
@@ -21,7 +19,6 @@ interface LinkMenuGroupProps {
     showEditor: (linkDoc: Doc) => void;
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
     docView: DocumentView;
-
 }
 
 @observer
@@ -44,27 +41,14 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         e.stopPropagation();
     }
 
-
     onLinkButtonMoved = async (e: PointerEvent) => {
-        UndoManager.RunInBatch(() => {
-            if (this._drag.current !== null && (e.movementX > 1 || e.movementY > 1)) {
-                document.removeEventListener("pointermove", this.onLinkButtonMoved);
-                document.removeEventListener("pointerup", this.onLinkButtonUp);
+        if (this._drag.current && (e.movementX > 1 || e.movementY > 1)) {
+            document.removeEventListener("pointermove", this.onLinkButtonMoved);
+            document.removeEventListener("pointerup", this.onLinkButtonUp);
 
-                const draggedDocs = this.props.group.map(linkDoc => {
-                    const opp = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc);
-                    if (opp) return opp;
-                }) as Doc[];
-                const dragData = new DragManager.DocumentDragData(draggedDocs);
-
-                DragManager.StartLinkedDocumentDrag([this._drag.current], dragData, e.x, e.y, {
-                    handlers: {
-                        dragComplete: action(emptyFunction),
-                    },
-                    hideSource: false
-                });
-            }
-        }, "drag links");
+            let targets = this.props.group.map(l => LinkManager.Instance.getOppositeAnchor(l, this.props.sourceDoc)).filter(d => d) as Doc[];
+            DragManager.StartLinkTargetsDrag(this._drag.current!, e.x, e.y, this.props.sourceDoc, targets);
+        }
         e.stopPropagation();
     }
 
diff --git a/src/client/views/linking/LinkMenuItem.scss b/src/client/views/linking/LinkMenuItem.scss
new file mode 100644
index 000000000..fd0954f65
--- /dev/null
+++ b/src/client/views/linking/LinkMenuItem.scss
@@ -0,0 +1,87 @@
+@import "../globalCssVariables";
+
+.linkMenu-item {
+    // border-top: 0.5px solid $main-accent; 
+    position: relative;
+    display: flex;
+    font-size: 12px;
+    
+
+    .linkMenu-name {
+        position: relative;
+
+        p {
+            padding: 4px 6px;
+            line-height: 12px;
+            border-radius: 5px;
+            overflow-wrap: break-word;
+            user-select: none;
+        }
+    }
+
+    .linkMenu-item-content {
+        width: 100%;
+    }
+    
+    .link-metadata {
+        padding: 0 10px 0 16px;
+        margin-bottom: 4px;
+        color: $main-accent;
+        font-style: italic;
+        font-size: 10.5px;
+    }
+
+    &:hover {
+        .linkMenu-item-buttons {
+            display: flex;
+        }
+        .linkMenu-item-content {
+            &.expand-two p {
+                width: calc(100% - 52px);
+                background-color: lightgray;
+            }
+            &.expand-three p {
+                width: calc(100% - 84px);
+                background-color: lightgray;
+            }
+        }
+    }
+}
+
+.linkMenu-item-buttons {
+    display: none;
+    position: absolute;
+    top: 50%;
+    right: 0;
+    transform: translateY(-50%);
+
+    .button {
+        width: 20px;
+        height: 20px;
+        margin: 0;
+        margin-right: 6px;
+        border-radius: 50%;
+        cursor: pointer;
+        pointer-events: auto;
+        background-color: $dark-color;
+        color: $light-color;
+        font-size: 65%;
+        transition: transform 0.2s;
+        text-align: center;
+        position: relative;
+
+        .fa-icon {
+            position: absolute;
+            top: 50%;
+            left: 50%;
+            transform: translate(-50%, -50%);
+        }
+
+        &:last-child {
+            margin-right: 0;
+        }
+        &:hover {
+            background: $main-accent;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index edf5e9c26..b7d27ee30 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -5,11 +5,11 @@ import { action, observable } from 'mobx';
 import { observer } from "mobx-react";
 import { Doc } from '../../../new_fields/Doc';
 import { Cast, StrCast } from '../../../new_fields/Types';
-import { DragLinkAsDocument } from '../../util/DragManager';
+import { DragManager } from '../../util/DragManager';
 import { LinkManager } from '../../util/LinkManager';
 import { ContextMenu } from '../ContextMenu';
 import { LinkFollowBox } from './LinkFollowBox';
-import './LinkMenu.scss';
+import './LinkMenuItem.scss';
 import React = require("react");
 library.add(faEye, faEdit, faTimes, faArrowRight, faChevronDown, faChevronUp);
 
@@ -26,6 +26,9 @@ interface LinkMenuItemProps {
 @observer
 export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     private _drag = React.createRef<HTMLDivElement>();
+    private _downX = 0;
+    private _downY = 0;
+    private _eleClone: any;
     @observable private _showMore: boolean = false;
     @action toggleShowMore() { this._showMore = !this._showMore; }
 
@@ -55,6 +58,9 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     }
 
     onLinkButtonDown = (e: React.PointerEvent): void => {
+        this._downX = e.clientX;
+        this._downY = e.clientY;
+        this._eleClone = this._drag.current!.cloneNode(true);
         e.stopPropagation();
         document.removeEventListener("pointermove", this.onLinkButtonMoved);
         document.addEventListener("pointermove", this.onLinkButtonMoved);
@@ -75,11 +81,12 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     }
 
     onLinkButtonMoved = async (e: PointerEvent) => {
-        if (this._drag.current !== null && (e.movementX > 1 || e.movementY > 1)) {
+        if (this._drag.current !== null && Math.abs((e.clientX - this._downX) * (e.clientX - this._downX) + (e.clientY - this._downY) * (e.clientY - this._downY)) > 5) {
             document.removeEventListener("pointermove", this.onLinkButtonMoved);
             document.removeEventListener("pointerup", this.onLinkButtonUp);
 
-            DragLinkAsDocument(this._drag.current, e.x, e.y, this.props.linkDoc, this.props.sourceDoc);
+            this._eleClone.style.transform = `translate(${e.x}px, ${e.y}px)`;
+            DragManager.StartLinkTargetsDrag(this._eleClone, e.x, e.y, this.props.sourceDoc, [this.props.linkDoc]);
         }
         e.stopPropagation();
     }
@@ -109,20 +116,21 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
     }
 
     render() {
-
         const keys = LinkManager.Instance.getMetadataKeysInGroup(this.props.groupType);//groupMetadataKeys.get(this.props.groupType);
         const canExpand = keys ? keys.length > 0 : false;
 
         return (
             <div className="linkMenu-item">
                 <div className={canExpand ? "linkMenu-item-content expand-three" : "linkMenu-item-content expand-two"}>
-                    <div className="link-name">
-                        <p ref={this._drag} onPointerDown={this.onLinkButtonDown}>{StrCast(this.props.destinationDoc.title)}</p>
+                    <div ref={this._drag} className="linkMenu-name" title="drag to view target. click to customize." onPointerDown={this.onLinkButtonDown}>
+                        <p >{StrCast(this.props.destinationDoc.title)}</p>
                         <div className="linkMenu-item-buttons">
                             {canExpand ? <div title="Show more" className="button" onPointerDown={() => this.toggleShowMore()}>
                                 <FontAwesomeIcon className="fa-icon" icon={this._showMore ? "chevron-up" : "chevron-down"} size="sm" /></div> : <></>}
                             <div title="Edit link" className="button" onPointerDown={this.onEdit}><FontAwesomeIcon className="fa-icon" icon="edit" size="sm" /></div>
-                            <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}><FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" /></div>
+                            <div title="Follow link" className="button" onClick={this.followDefault} onContextMenu={this.onContextMenu}>
+                                <FontAwesomeIcon className="fa-icon" icon="arrow-right" size="sm" />
+                            </div>
                         </div>
                     </div>
                     {this._showMore ? this.renderMetadata() : <></>}
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index 34151a311..d1272c266 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -46,7 +46,7 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
             this.dropDisposer();
         }
         if (ele) {
-            this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } });
+            this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
         }
     }
 
@@ -65,9 +65,10 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData && e.target) {
-            this.props.Document[(e.target as any).textContent] = new List<Doc>(de.data.droppedDocuments.map((d, i) =>
-                d.onDragStart ? de.data.draggedDocuments[i] : d));
+        const docDragData = de.complete.docDragData;
+        if (docDragData && e.target) {
+            this.props.Document[(e.target as any).textContent] = new List<Doc>(docDragData.droppedDocuments.map((d, i) =>
+                d.onDragStart ? docDragData.draggedDocuments[i] : d));
             e.stopPropagation();
         }
     }
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 6d0ea33fa..5e3306a11 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -32,7 +32,7 @@ interface ContentFittingDocumentViewProps {
     onClick?: ScriptField;
     getTransform: () => Transform;
     addDocument: (document: Doc) => boolean;
-    moveDocument: (document: Doc, target: Doc, addDoc: ((doc: Doc) => boolean)) => boolean;
+    moveDocument: (document: Doc, target: Doc | undefined, addDoc: ((doc: Doc) => boolean)) => boolean;
     removeDocument: (document: Doc) => boolean;
     active: (outsideReaction: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
@@ -60,11 +60,12 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
+        const docDragData = de.complete.docDragData;
+        if (docDragData) {
             this.props.childDocs && this.props.childDocs.map(otherdoc => {
                 const target = Doc.GetProto(otherdoc);
                 target.layout = ComputedField.MakeFunction("this.image_data[0]");
-                target.layoutCustom = Doc.MakeDelegate(de.data.draggedDocuments[0]);
+                target.layoutCustom = Doc.MakeDelegate(docDragData.draggedDocuments[0]);
             });
             e.stopPropagation();
         }
diff --git a/src/client/views/nodes/DocuLinkBox.tsx b/src/client/views/nodes/DocuLinkBox.tsx
index a22472e9e..3e2e74c67 100644
--- a/src/client/views/nodes/DocuLinkBox.tsx
+++ b/src/client/views/nodes/DocuLinkBox.tsx
@@ -5,7 +5,7 @@ import { makeInterface } from "../../../new_fields/Schema";
 import { NumCast, StrCast, Cast } from "../../../new_fields/Types";
 import { Utils } from '../../../Utils';
 import { DocumentManager } from "../../util/DocumentManager";
-import { DragLinksAsDocuments } from "../../util/DragManager";
+import { DragManager } from "../../util/DragManager";
 import { DocComponent } from "../DocComponent";
 import "./DocuLinkBox.scss";
 import { FieldView, FieldViewProps } from "./FieldView";
@@ -43,7 +43,7 @@ export class DocuLinkBox extends DocComponent<FieldViewProps, DocLinkSchema>(Doc
             const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
             const dragdist = Math.sqrt((pt[0] - this._downx) * (pt[0] - this._downx) + (pt[1] - this._downy) * (pt[1] - this._downy));
             if (separation > 100) {
-                DragLinksAsDocuments(this._ref.current!, pt[0], pt[1], Cast(this.props.Document[this.props.fieldKey], Doc) as Doc, this.props.Document); // Containging collection is the document, not a collection... hack.
+                DragManager.StartLinkTargetsDrag(this._ref.current!, pt[0], pt[1], Cast(this.props.Document[this.props.fieldKey], Doc) as Doc, [this.props.Document]); // Containging collection is the document, not a collection... hack.
                 document.removeEventListener("pointermove", this.onPointerMove);
                 document.removeEventListener("pointerup", this.onPointerUp);
             } else if (dragdist > separation) {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1b2d92027..b096d68fc 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -19,7 +19,6 @@ import { DocumentType } from '../../documents/DocumentTypes';
 import { ClientUtils } from '../../util/ClientUtils';
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager, dropActionType } from "../../util/DragManager";
-import { LinkManager } from '../../util/LinkManager';
 import { Scripting } from '../../util/Scripting';
 import { SelectionManager } from "../../util/SelectionManager";
 import SharingManager from '../../util/SharingManager';
@@ -60,7 +59,7 @@ export interface DocumentViewProps {
     dragDivName?: string;
     addDocument?: (doc: Doc) => boolean;
     removeDocument?: (doc: Doc) => boolean;
-    moveDocument?: (doc: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument?: (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     renderDepth: number;
     showOverlays?: (doc: Doc) => { title?: string, caption?: string };
@@ -105,7 +104,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @action
     componentDidMount() {
-        this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }));
+        this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
 
         !this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.push(this);
     }
@@ -113,7 +112,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @action
     componentDidUpdate() {
         this._dropDisposer && this._dropDisposer();
-        this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } }));
+        this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
     }
 
     @action
@@ -132,12 +131,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             dragData.moveDocument = this.Document.onDragStart ? undefined : this.props.moveDocument;
             dragData.applyAsTemplate = applyAsTemplate;
             dragData.dragDivName = this.props.dragDivName;
-            DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, {
-                handlers: {
-                    dragComplete: action((emptyFunction))
-                },
-                hideSource: !dropAction && !this.Document.onDragStart
-            });
+            DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.Document.onDragStart });
         }
     }
 
@@ -190,7 +184,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     buttonClick = async (altKey: boolean, ctrlKey: boolean) => {
         const maximizedDocs = await DocListCastAsync(this.Document.maximizedDocs);
         const summarizedDocs = await DocListCastAsync(this.Document.summarizedDocs);
-        const linkDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
+        const linkDocs = DocListCast(this.props.Document.links);
         let expandedDocs: Doc[] = [];
         expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs;
         expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs;
@@ -324,23 +318,24 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @undoBatch
     @action
     drop = async (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.AnnotationDragData) {
+        if (de.complete.annoDragData) {
             /// this whole section for handling PDF annotations looks weird.  Need to rethink this to make it cleaner
             e.stopPropagation();
-            (de.data as any).linkedToDoc = true;
+            de.complete.annoDragData.linkedToDoc = true;
 
-            DocUtils.MakeLink({ doc: de.data.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `Link from ${StrCast(de.data.annotationDocument.title)}`);
+            DocUtils.MakeLink({ doc: de.complete.annoDragData.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc },
+                `Link from ${StrCast(de.complete.annoDragData.annotationDocument.title)}`);
         }
-        if (de.data instanceof DragManager.DocumentDragData && de.data.applyAsTemplate) {
-            Doc.ApplyTemplateTo(de.data.draggedDocuments[0], this.props.Document, "layoutCustom");
+        if (de.complete.docDragData && de.complete.docDragData.applyAsTemplate) {
+            Doc.ApplyTemplateTo(de.complete.docDragData.draggedDocuments[0], this.props.Document, "layoutCustom");
             e.stopPropagation();
         }
-        if (de.data instanceof DragManager.LinkDragData) {
+        if (de.complete.linkDragData) {
             e.stopPropagation();
             // const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
             // const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
-            de.data.linkSourceDocument !== this.props.Document &&
-                (de.data.linkDocument = DocUtils.MakeLink({ doc: de.data.linkSourceDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "in-text link being created")); // TODODO this is where in text links get passed
+            de.complete.linkDragData.linkSourceDocument !== this.props.Document &&
+                (de.complete.linkDragData.linkDocument = DocUtils.MakeLink({ doc: de.complete.linkDragData.linkSourceDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "in-text link being created")); // TODODO this is where in text links get passed
         }
     }
 
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index ce1c468ad..c56fde186 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -39,7 +39,7 @@ export interface FieldViewProps {
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     removeDocument?: (document: Doc) => boolean;
-    moveDocument?: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
+    moveDocument?: (document: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     active: (outsideReaction?: boolean) => boolean;
     whenActiveChanged: (isActive: boolean) => void;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 7d404b28f..af09e57f4 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -246,22 +246,22 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     protected createDropTarget = (ele: HTMLDivElement) => {
         this._proseRef = ele;
         this.dropDisposer && this.dropDisposer();
-        ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }));
+        ele && (this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)));
     }
 
     @undoBatch
     @action
     drop = async (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
-            const draggedDoc = de.data.draggedDocuments.length && de.data.draggedDocuments[0];
+        if (de.complete.docDragData) {
+            const draggedDoc = de.complete.docDragData.draggedDocuments.length && de.complete.docDragData.draggedDocuments[0];
             // replace text contents whend dragging with Alt
-            if (draggedDoc && draggedDoc.type === DocumentType.TEXT && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.mods === "AltKey") {
+            if (draggedDoc && draggedDoc.type === DocumentType.TEXT && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.altKey) {
                 if (draggedDoc.data instanceof RichTextField) {
                     Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new RichTextField(draggedDoc.data.Data, draggedDoc.data.Text);
                     e.stopPropagation();
                 }
                 // apply as template when dragging with Meta
-            } else if (draggedDoc && draggedDoc.type === DocumentType.TEXT && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.mods === "MetaKey") {
+            } else if (draggedDoc && draggedDoc.type === DocumentType.TEXT && !Doc.AreProtosEqual(draggedDoc, this.props.Document) && de.metaKey) {
                 draggedDoc.isTemplateDoc = true;
                 let newLayout = Doc.Layout(draggedDoc);
                 if (typeof (draggedDoc.layout) === "string") {
@@ -272,8 +272,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 this.Document.layoutKey = "layoutCustom";
                 e.stopPropagation();
                 // embed document when dragging with a userDropAction or an embedDoc flag set
-            } else if (de.data.userDropAction || de.data.embedDoc) {
-                const target = de.data.droppedDocuments[0];
+            } else if (de.complete.docDragData.userDropAction || de.complete.docDragData.embedDoc) {
+                const target = de.complete.docDragData.droppedDocuments[0];
                 // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title);
                 // if (link) {
                 target.fitToBox = true;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 4b3da3dae..f6aa47f15 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -67,18 +67,18 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     protected createDropTarget = (ele: HTMLDivElement) => {
         this._dropDisposer && this._dropDisposer();
-        ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.drop.bind(this) } }));
+        ele && (this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this)));
     }
 
     @undoBatch
     @action
     drop = (e: Event, de: DragManager.DropEvent) => {
-        if (de.data instanceof DragManager.DocumentDragData) {
-            if (de.mods === "AltKey" && de.data.draggedDocuments.length && de.data.draggedDocuments[0].data instanceof ImageField) {
-                Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new ImageField(de.data.draggedDocuments[0].data.url);
+        if (de.complete.docDragData) {
+            if (de.altKey && de.complete.docDragData.draggedDocuments.length && de.complete.docDragData.draggedDocuments[0].data instanceof ImageField) {
+                Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new ImageField(de.complete.docDragData.draggedDocuments[0].data.url);
                 e.stopPropagation();
             }
-            de.mods === "MetaKey" && de.data.droppedDocuments.forEach(action((drop: Doc) => {
+            de.metaKey && de.complete.docDragData.droppedDocuments.forEach(action((drop: Doc) => {
                 this.extensionDoc && Doc.AddDocToList(Doc.GetProto(this.extensionDoc), "Alternates", drop);
                 e.stopPropagation();
             }));
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index b114cd7ed..c85350264 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -409,6 +409,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         if ((this.Document.scale || 1) !== 1) return;
         if ((e.button !== 0 || e.altKey) && this.active(true)) {
             this._setPreviewCursor && this._setPreviewCursor(e.clientX, e.clientY, true);
+            e.stopPropagation();
         }
         this._marqueeing = false;
         if (!e.altKey && e.button === 0 && this.active(true)) {
@@ -559,14 +560,9 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         const targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
         const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
         if (annotationDoc) {
-            const dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
-            DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
-                handlers: {
-                    dragComplete: () => !(dragData as any).linkedToDoc &&
-                        DocUtils.MakeLink({ doc: annotationDoc }, { doc: dragData.dropDocument, ctx: dragData.targetContext }, `Annotation from ${this.Document.title}`, "link from PDF")
-
-                },
-                hideSource: false
+            DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
+                dragComplete: e => !e.aborted && e.annoDragData && !e.annoDragData.linkedToDoc &&
+                    DocUtils.MakeLink({ doc: annotationDoc }, { doc: e.annoDragData.dropDocument, ctx: e.annoDragData.targetContext }, `Annotation from ${this.Document.title}`, "link from PDF")
             });
         }
     }
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index fe21c29c3..515c248f7 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -12,13 +12,11 @@ import { Utils } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { SetupDrag } from '../../util/DragManager';
 import { SearchUtil } from '../../util/SearchUtil';
-import { MainView } from '../MainView';
 import { FilterBox } from './FilterBox';
 import "./FilterBox.scss";
 import "./SearchBox.scss";
 import { SearchItem } from './SearchItem';
 import { IconBar } from './IconBar';
-import { string } from 'prop-types';
 
 library.add(faTimes);
 
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index cdb6dcf7c..8cd4b3caa 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -4,14 +4,13 @@ import { faCaretUp, faChartBar, faFile, faFilePdf, faFilm, faFingerprint, faGlob
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { emptyFunction, returnEmptyString, returnFalse, returnOne, Utils, emptyPath } from "../../../Utils";
 import { DocumentType } from "../../documents/DocumentTypes";
 import { DocumentManager } from "../../util/DocumentManager";
 import { DragManager, SetupDrag } from "../../util/DragManager";
-import { LinkManager } from "../../util/LinkManager";
 import { SearchUtil } from "../../util/SearchUtil";
 import { Transform } from "../../util/Transform";
 import { SEARCH_THUMBNAIL_SIZE } from "../../views/globalCssVariables.scss";
@@ -211,7 +210,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
     }
 
     @computed
-    get linkCount() { return LinkManager.Instance.getAllRelatedLinks(this.props.doc).length; }
+    get linkCount() { return DocListCast(this.props.doc.links).length; }
 
     @action
     pointerDown = (e: React.PointerEvent) => { e.preventDefault(); e.button === 0 && SearchBox.Instance.openSearch(e); }
@@ -267,10 +266,7 @@ export class SearchItem extends React.Component<SearchItemProps> {
     onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {
         e.stopPropagation();
         const doc = Doc.IsPrototype(this.props.doc) ? Doc.MakeDelegate(this.props.doc) : this.props.doc;
-        DragManager.StartDocumentDrag([e.currentTarget], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY, {
-            handlers: { dragComplete: emptyFunction },
-            hideSource: false,
-        });
+        DragManager.StartDocumentDrag([e.currentTarget], new DragManager.DocumentDragData([doc]), e.clientX, e.clientY);
     }
 
     render() {
-- 
cgit v1.2.3-70-g09d2


From 8ada1b069d4183fb85d19c67a151cad186625f26 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 18 Dec 2019 17:52:27 -0500
Subject: fixes to fieldKey searces within layoutstrings to use ' instead of "

---
 src/client/util/DropConverter.ts                        | 2 +-
 src/client/views/DocumentDecorations.tsx                | 2 +-
 src/client/views/collections/CollectionStackingView.tsx | 2 +-
 src/client/views/nodes/FormattedTextBox.tsx             | 2 +-
 src/new_fields/Doc.ts                                   | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 349d5d7e3..9e036d6c2 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -10,7 +10,7 @@ import { ScriptField } from "../../new_fields/ScriptField";
 
 function makeTemplate(doc: Doc): boolean {
     const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
-    const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^"]*'}/)![0];
+    const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)![0];
     const fieldKey = layout.replace("fieldKey={'", "").replace(/'}$/, "");
     const docs = DocListCast(layoutDoc[fieldKey]);
     let any = false;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 228cea00e..3905bffed 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -118,7 +118,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                     fieldTemplate.title = metaKey;
                     Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate));
                     if (text.startsWith(">>")) {
-                        Doc.GetProto(docTemplate).layout = StrCast(fieldTemplateView.props.Document.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
+                        Doc.GetProto(docTemplate).layout = StrCast(fieldTemplateView.props.Document.layout).replace(/fieldKey={'[^']*'}/, `fieldKey={"${metaKey}"}`);
                     }
                 }
             }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 6a23920f3..75cf213b7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -171,7 +171,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             DataDocument={dataDoc}
             LibraryPath={this.props.LibraryPath}
             showOverlays={this.overlays}
-            renderDepth={this.props.renderDepth}
+            renderDepth={this.props.renderDepth + 1}
             ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
             fitToBox={this.props.fitToBox}
             onClick={layoutDoc.isTemplateDoc ? this.onClickHandler : this.onChildClickHandler}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index b19729811..662cc9aea 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -266,7 +266,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 let newLayout = Doc.Layout(draggedDoc);
                 if (typeof (draggedDoc.layout) === "string") {
                     newLayout = Doc.MakeDelegate(draggedDoc);
-                    newLayout.layout = StrCast(newLayout.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${this.props.fieldKey}"}`);
+                    newLayout.layout = StrCast(newLayout.layout).replace(/fieldKey={'[^']*'}/, `fieldKey={'${this.props.fieldKey}'}`);
                 }
                 this.Document.layoutCustom = newLayout;
                 this.Document.layoutKey = "layoutCustom";
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 168e42b77..a969a8359 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -609,7 +609,7 @@ export namespace Doc {
         const data = fieldTemplate.data;
         // setTimeout(action(() => {
         !templateDataDoc[metadataFieldName] && data instanceof ObjectField && (Doc.GetProto(templateDataDoc)[metadataFieldName] = ObjectField.MakeCopy(data));
-        const layout = StrCast(fieldLayoutDoc.layout).replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metadataFieldName}"}`);
+        const layout = StrCast(fieldLayoutDoc.layout).replace(/fieldKey={'[^']*'}/, `fieldKey={'${metadataFieldName}'}`);
         const layoutDelegate = Doc.Layout(fieldTemplate);
         layoutDelegate.layout = layout;
         fieldTemplate.layout = layoutDelegate !== fieldTemplate ? layoutDelegate : layout;
-- 
cgit v1.2.3-70-g09d2


From 582cf89686c55b164d60cfdd85090ac5267ba2eb Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 18 Dec 2019 19:09:32 -0500
Subject: fixed dropping on stacks a little bit.  problem still exists with
 stackinview that has multiple columns because children() is called for each
 stack, but resets DocXfs

---
 src/client/views/collections/CollectionStackingView.tsx | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 75cf213b7..83ac81103 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -25,6 +25,7 @@ import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 import { TraceMobx } from "../../../new_fields/util";
+import { CollectionViewType } from "./CollectionView";
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -165,7 +166,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
         const layoutDoc = Doc.Layout(doc);
         const height = () => this.getDocHeight(doc);
-        const finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
+        const finalDxf = () => dxf();
         return <ContentFittingDocumentView
             Document={doc}
             DataDocument={dataDoc}
@@ -242,14 +243,15 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     drop = (e: Event, de: DragManager.DropEvent) => {
         const where = [de.x, de.y];
         let targInd = -1;
-        let plusOne = false;
+        let plusOne = 0;
         if (de.complete.docDragData) {
             this._docXfs.map((cd, i) => {
                 const pos = cd.dxf().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
                 const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
                 if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
                     targInd = i;
-                    plusOne = (where[1] > (pos[1] + pos1[1]) / 2 ? 1 : 0) ? true : false;
+                    let axis = this.Document.viewType === CollectionViewType.Masonry ? 0 : 1;
+                    plusOne = where[axis] > (pos[axis] + pos1[axis]) / 2 ? 1 : 0;
                 }
             });
             if (super.drop(e, de)) {
@@ -260,7 +262,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     else targInd = docs.indexOf(this.filteredChildren[targInd]);
                     const srcInd = docs.indexOf(newDoc);
                     docs.splice(srcInd, 1);
-                    docs.splice((targInd > srcInd ? targInd - 1 : targInd) + (plusOne ? 1 : 0), 0, newDoc);
+                    docs.splice((targInd > srcInd ? targInd - 1 : targInd) + plusOne, 0, newDoc);
                 }
             }
         }
@@ -320,8 +322,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         const outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
         const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
         return this.props.ScreenToLocalTransform().
-            translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0)).
-            scale(NumCast(doc.width, 1) / this.columnWidth);
+            translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
     }
 
     sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
-- 
cgit v1.2.3-70-g09d2


From 306ea362cad253764bc632d6274ae71a45ecd85c Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 19 Dec 2019 16:27:13 -0500
Subject: compiler fixes.  fix for text box titles on templates

---
 src/client/util/SearchUtil.ts                           |  4 ++--
 src/client/views/DocumentDecorations.tsx                |  2 +-
 src/client/views/collections/CollectionStackingView.tsx |  5 ++---
 src/client/views/nodes/DocumentView.tsx                 | 10 +++++-----
 src/server/authentication/models/current_user_utils.ts  |  2 +-
 5 files changed, 11 insertions(+), 12 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/util/SearchUtil.ts b/src/client/util/SearchUtil.ts
index 4f6211d94..8ff54d052 100644
--- a/src/client/util/SearchUtil.ts
+++ b/src/client/util/SearchUtil.ts
@@ -34,8 +34,8 @@ export namespace SearchUtil {
     export function Search(query: string, returnDocs: false, options?: SearchParams): Promise<IdSearchResult>;
     export async function Search(query: string, returnDocs: boolean, options: SearchParams = {}) {
         query = query || "*"; //If we just have a filter query, search for * as the query
-        let rpquery = Utils.prepend("/search");
-        let gotten = await rp.get(rpquery, { qs: { ...options, q: query } });
+        const rpquery = Utils.prepend("/search");
+        const gotten = await rp.get(rpquery, { qs: { ...options, q: query } });
         const result: IdSearchResult = gotten.startsWith("<") ? { ids: [], docs: [], numFound: 0, lines: [] } : JSON.parse(gotten);
         if (!returnDocs) {
             return result;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 3905bffed..4bc24fa93 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -233,7 +233,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
         e.stopPropagation();
         if (e.button === 0) {
             const recent = Cast(CurrentUserUtils.UserDocument.recentlyClosed, Doc) as Doc;
-            let selected = SelectionManager.SelectedDocuments().slice();
+            const selected = SelectionManager.SelectedDocuments().slice();
             SelectionManager.DeselectAll();
             selected.map(dv => {
                 recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 83ac81103..e71e11b48 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -166,7 +166,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     getDisplayDoc(doc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
         const layoutDoc = Doc.Layout(doc);
         const height = () => this.getDocHeight(doc);
-        const finalDxf = () => dxf();
         return <ContentFittingDocumentView
             Document={doc}
             DataDocument={dataDoc}
@@ -178,7 +177,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             onClick={layoutDoc.isTemplateDoc ? this.onClickHandler : this.onChildClickHandler}
             PanelWidth={width}
             PanelHeight={height}
-            getTransform={finalDxf}
+            getTransform={dxf}
             focus={this.props.focus}
             CollectionDoc={this.props.CollectionView && this.props.CollectionView.props.Document}
             CollectionView={this.props.CollectionView}
@@ -250,7 +249,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
                 if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
                     targInd = i;
-                    let axis = this.Document.viewType === CollectionViewType.Masonry ? 0 : 1;
+                    const axis = this.Document.viewType === CollectionViewType.Masonry ? 0 : 1;
                     plusOne = where[axis] > (pos[axis] + pos1[axis]) / 2 ? 1 : 0;
                 }
             });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6ea5b2d2a..63c17b1f6 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -159,7 +159,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             e.preventDefault();
             if (e.key === "†" || e.key === "t") {
-                if (!StrCast(this.Document.showTitle)) this.Document.showTitle = "title";
+                if (!StrCast(this.layoutDoc.showTitle)) this.layoutDoc.showTitle = "title";
                 if (!this._titleRef.current) setTimeout(() => this._titleRef.current?.setIsFocused(true), 0);
                 else if (!this._titleRef.current.setIsFocused(true)) { // if focus didn't change, focus on interior text...
                     {
@@ -587,7 +587,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     // does Document set a layout prop 
-    setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)];
+    setsLayoutProp = (prop: string) => this.props.Document[prop] !== this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)] && this.props.Document["default" + prop[0].toUpperCase() + prop.slice(1)];
     // get the a layout prop by first choosing the prop from Document, then falling back to the layout doc otherwise.
     getLayoutPropStr = (prop: string) => StrCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
     getLayoutPropNum = (prop: string) => NumCast(this.setsLayoutProp(prop) ? this.props.Document[prop] : this.layoutDoc[prop]);
@@ -597,7 +597,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     chromeHeight = () => {
         const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
-        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.Document.showTitle);
+        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.layoutDoc.showTitle);
         return (showTitle ? 25 : 0) + 1;
     }
 
@@ -651,9 +651,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @computed get innards() {
         TraceMobx();
         const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
-        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : this.getLayoutPropStr("showTitle");
+        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.getLayoutPropStr("showTitle"));
         const showCaption = showOverlays && "caption" in showOverlays ? showOverlays.caption : this.getLayoutPropStr("showCaption");
-        const showTextTitle = showTitle && StrCast(this.Document.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined;
+        const showTextTitle = showTitle && StrCast(this.layoutDoc.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined;
         const searchHighlight = (!this.Document.searchFields ? (null) :
             <div className="documentView-searchHighlight">
                 {this.Document.searchFields}
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 120c75fe8..220c37e2b 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -80,7 +80,7 @@ export class CurrentUserUtils {
                     if (dragset) {
                         const dragdocs = await Cast(dragset.data, listSpec(Doc));
                         if (dragdocs) {
-                            const dragDocs = await Promise.all(dragdocs.map(async d => await d));
+                            const dragDocs = await Promise.all(dragdocs);
                             const newButtons = this.setupCreatorButtons(doc, dragDocs.map(d => StrCast(d.title)));
                             newButtons.map(nb => Doc.AddDocToList(dragset, "data", nb));
                         }
-- 
cgit v1.2.3-70-g09d2


From cef6852d597ce67637466afb36c3498dc84211f6 Mon Sep 17 00:00:00 2001
From: Stanley Yip <stanley_yip@brown.edu>
Date: Wed, 8 Jan 2020 19:48:28 -0500
Subject: gestures are now overlayed and can span collections/panes!

---
 src/client/documents/Documents.ts                  |   3 +-
 src/client/views/CollectionLinearView.tsx          |   4 +-
 src/client/views/GestureOverlay.scss               |   8 +
 src/client/views/GestureOverlay.tsx                | 159 +++++++++++++++++++
 src/client/views/InkSelectDecorations.scss         |   5 -
 src/client/views/InkSelectDecorations.tsx          |  55 -------
 src/client/views/InkingStroke.tsx                  |   6 +-
 src/client/views/MainView.scss                     |   7 +-
 src/client/views/MainView.tsx                      |   7 +-
 .../views/collections/CollectionStackingView.tsx   |   6 +-
 src/client/views/collections/CollectionSubView.tsx |  13 +-
 .../views/collections/CollectionTreeView.scss      |   6 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 171 +++++++--------------
 src/client/views/nodes/DocumentView.tsx            |  19 ++-
 src/pen-gestures/GestureUtils.ts                   |  28 +++-
 15 files changed, 299 insertions(+), 198 deletions(-)
 create mode 100644 src/client/views/GestureOverlay.scss
 create mode 100644 src/client/views/GestureOverlay.tsx
 delete mode 100644 src/client/views/InkSelectDecorations.scss
 delete mode 100644 src/client/views/InkSelectDecorations.tsx

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e149963b9..1853be529 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -29,7 +29,7 @@ import { listSpec } from "../../new_fields/Schema";
 import { DocServer } from "../DocServer";
 import { dropActionType } from "../util/DragManager";
 import { DateField } from "../../new_fields/DateField";
-import { UndoManager } from "../util/UndoManager";
+import { UndoManager, undoBatch } from "../util/UndoManager";
 import { YoutubeBox } from "../apis/youtube/YoutubeBox";
 import { CollectionDockingView } from "../views/collections/CollectionDockingView";
 import { LinkManager } from "../util/LinkManager";
@@ -730,6 +730,7 @@ export namespace DocUtils {
         });
     }
 
+    @undoBatch
     export function MakeLink(source: { doc: Doc, ctx?: Doc }, target: { doc: Doc, ctx?: Doc }, title: string = "", description: string = "", id?: string) {
         const sv = DocumentManager.Instance.getDocumentView(source.doc);
         if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index 5ca861f71..5d6a58656 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -36,7 +36,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
             { fireImmediately: true }
         );
     }
-    protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+    protected createDropAndGestureTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
         this._dropDisposer && this._dropDisposer();
         if (ele) {
             this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
@@ -55,7 +55,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
     render() {
         const guid = Utils.GenerateGuid();
         return <div className="collectionLinearView-outer">
-            <div className="collectionLinearView" ref={this.createDropTarget} >
+            <div className="collectionLinearView" ref={this.createDropAndGestureTarget} >
                 <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
                     onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
                 <label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
diff --git a/src/client/views/GestureOverlay.scss b/src/client/views/GestureOverlay.scss
new file mode 100644
index 000000000..cbc1b6e7d
--- /dev/null
+++ b/src/client/views/GestureOverlay.scss
@@ -0,0 +1,8 @@
+.gestureOverlay-cont {
+    width: 100vw;
+    height: 100vw;
+    position: absolute;
+    top: 0;
+    left: 0;
+    touch-action: none;
+}
\ No newline at end of file
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
new file mode 100644
index 000000000..c88e3f7ae
--- /dev/null
+++ b/src/client/views/GestureOverlay.tsx
@@ -0,0 +1,159 @@
+import React = require("react");
+import { Touchable } from "./Touchable";
+import { observer } from "mobx-react";
+import "./GestureOverlay.scss"
+import { computed, observable, action } from "mobx";
+import { CreatePolyline } from "./InkingStroke";
+import { GestureUtils } from "../../pen-gestures/GestureUtils";
+import { InteractionUtils } from "../util/InteractionUtils";
+import { InkingControl } from "./InkingControl";
+import { InkTool } from "../../new_fields/InkField";
+import { Doc } from "../../new_fields/Doc";
+import { LinkManager } from "../util/LinkManager";
+import { DocUtils } from "../documents/Documents";
+import { undoBatch } from "../util/UndoManager";
+
+@observer
+export default class GestureOverlay extends Touchable {
+    static Instance: GestureOverlay;
+
+    @observable private _points: { X: number, Y: number }[] = [];
+
+    private _d1: Doc | undefined;
+
+    constructor(props: Readonly<{}>) {
+        super(props);
+
+        GestureOverlay.Instance = this;
+    }
+
+    @action
+    onPointerDown = (e: React.PointerEvent) => {
+        if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
+            this._points.push({ X: e.clientX, Y: e.clientY });
+            e.stopPropagation();
+            e.preventDefault();
+
+            document.removeEventListener("pointermove", this.onPointerMove);
+            document.removeEventListener("pointerup", this.onPointerUp);
+            document.addEventListener("pointermove", this.onPointerMove);
+            document.addEventListener("pointerup", this.onPointerUp);
+        }
+    }
+
+    @action
+    onPointerMove = (e: PointerEvent) => {
+        this._points.push({ X: e.clientX, Y: e.clientY });
+        e.stopPropagation();
+        e.preventDefault();
+    }
+
+    @action
+    onPointerUp = (e: PointerEvent) => {
+        if (this._points.length > 1) {
+            const B = this.svgBounds;
+            const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
+
+            const result = GestureUtils.GestureRecognizer.Recognize(new Array(points));
+            let actionPerformed = false;
+            if (result && result.Score > 0.7) {
+                switch (result.Name) {
+                    case GestureUtils.Gestures.Box:
+                        const target = document.elementFromPoint(this._points[0].X, this._points[0].Y);
+                        target?.dispatchEvent(new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
+                            {
+                                bubbles: true,
+                                detail: {
+                                    points: this._points,
+                                    gesture: GestureUtils.Gestures.Box,
+                                    bounds: B
+                                }
+                            }));
+                        actionPerformed = true;
+                        break;
+                    case GestureUtils.Gestures.Line:
+                        const ep1 = this._points[0];
+                        const ep2 = this._points[this._points.length - 1];
+                        const target1 = document.elementFromPoint(ep1.X, ep1.Y);
+                        const target2 = document.elementFromPoint(ep2.X, ep2.Y);
+                        const callback = (doc: Doc) => {
+                            if (!this._d1) {
+                                this._d1 = doc;
+                            }
+                            else if (this._d1 !== doc && !LinkManager.Instance.doesLinkExist(this._d1, doc)) {
+                                DocUtils.MakeLink({ doc: this._d1 }, { doc: doc });
+                                actionPerformed = true;
+                            }
+                        }
+                        const ge = new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
+                            {
+                                bubbles: true,
+                                detail: {
+                                    points: this._points,
+                                    gesture: GestureUtils.Gestures.Line,
+                                    bounds: B,
+                                    callbackFn: callback
+                                }
+                            })
+                        target1?.dispatchEvent(ge);
+                        target2?.dispatchEvent(ge);
+                        break;
+                }
+                if (actionPerformed) {
+                    this._points = [];
+                }
+            }
+
+            if (!actionPerformed) {
+                const target = document.elementFromPoint(this._points[0].X, this._points[0].Y);
+                target?.dispatchEvent(
+                    new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
+                        {
+                            bubbles: true,
+                            detail: {
+                                points: this._points,
+                                gesture: GestureUtils.Gestures.Stroke,
+                                bounds: B
+                            }
+                        }
+                    )
+                )
+                this._points = [];
+            }
+        }
+        document.removeEventListener("pointermove", this.onPointerMove);
+        document.removeEventListener("pointerup", this.onPointerUp);
+    }
+
+    @computed get svgBounds() {
+        const xs = this._points.map(p => p.X);
+        const ys = this._points.map(p => p.Y);
+        const right = Math.max(...xs);
+        const left = Math.min(...xs);
+        const bottom = Math.max(...ys);
+        const top = Math.min(...ys);
+        return { right: right, left: left, bottom: bottom, top: top, width: right - left, height: bottom - top };
+    }
+
+    @computed get currentStroke() {
+        if (this._points.length <= 1) {
+            return (null);
+        }
+
+        const B = this.svgBounds;
+
+        return (
+            <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)`, pointerEvents: "none", position: "absolute", zIndex: 30000 }}>
+                {CreatePolyline(this._points, B.left, B.top)}
+            </svg>
+        );
+    }
+
+    render() {
+        return (
+            <div className="gestureOverlay-cont" onPointerDown={this.onPointerDown}>
+                {this.props.children}
+                {this.currentStroke}
+            </div>);
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/InkSelectDecorations.scss b/src/client/views/InkSelectDecorations.scss
deleted file mode 100644
index daff58fd6..000000000
--- a/src/client/views/InkSelectDecorations.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-.inkSelectDecorations {
-    position: absolute;
-    border: black 1px solid;
-    z-index: 9001;
-}
\ No newline at end of file
diff --git a/src/client/views/InkSelectDecorations.tsx b/src/client/views/InkSelectDecorations.tsx
deleted file mode 100644
index 3ad50762d..000000000
--- a/src/client/views/InkSelectDecorations.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import React = require("react");
-import { Touchable } from "./Touchable";
-import { PointData } from "../../new_fields/InkField";
-import { observer } from "mobx-react";
-import { computed, observable, action, runInAction } from "mobx";
-import "./InkSelectDecorations.scss";
-
-@observer
-export default class InkSelectDecorations extends Touchable {
-    static Instance: InkSelectDecorations;
-
-    @observable private _selectedInkNodes: Map<any, any> = new Map();
-
-    constructor(props: Readonly<{}>) {
-        super(props);
-
-        InkSelectDecorations.Instance = this;
-    }
-
-    @action
-    public SetSelected = (inkNodes: Map<any, any>, keepOld: boolean = false) => {
-        if (!keepOld) {
-            this._selectedInkNodes = new Map();
-        }
-        inkNodes.forEach((value: any, key: any) => {
-            runInAction(() => this._selectedInkNodes.set(key, value));
-        });
-    }
-
-    @computed
-    get Bounds(): { x: number, y: number, b: number, r: number } {
-        const left = Number.MAX_VALUE;
-        const top = Number.MAX_VALUE;
-        const right = -Number.MAX_VALUE;
-        const bottom = -Number.MAX_VALUE;
-        this._selectedInkNodes.forEach((value: PointData, key: string) => {
-            // value.pathData.map(val => {
-            //     left = Math.min(val.x, left);
-            //     top = Math.min(val.y, top);
-            //     right = Math.max(val.x, right);
-            //     bottom = Math.max(val.y, bottom);
-            // });
-        });
-        return { x: left, y: top, b: bottom, r: right };
-    }
-
-    render() {
-        const bounds = this.Bounds;
-        return <div style={{
-            top: bounds.y, left: bounds.x,
-            height: bounds.b - bounds.y,
-            width: bounds.r - bounds.x
-        }} />;
-    }
-}
\ No newline at end of file
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index a413eebc9..8b346d5d9 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -9,6 +9,7 @@ import { InkingControl } from "./InkingControl";
 import "./InkingStroke.scss";
 import { FieldView, FieldViewProps } from "./nodes/FieldView";
 import React = require("react");
+import { TraceMobx } from "../../new_fields/util";
 
 type InkDocument = makeInterface<[typeof documentSchema]>;
 const InkDocument = makeInterface(documentSchema);
@@ -35,6 +36,7 @@ export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocu
     @computed get PanelHeight() { return this.props.PanelHeight(); }
 
     render() {
+        TraceMobx();
         const data: InkData = Cast(this.Document.data, InkField)?.inkData ?? [];
         const xs = data.map(p => p.X);
         const ys = data.map(p => p.Y);
@@ -42,7 +44,7 @@ export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocu
         const top = Math.min(...ys);
         const right = Math.max(...xs);
         const bottom = Math.max(...ys);
-        const points = CreatePolyline(data, 0, 0, this.Document.color, this.Document.strokeWidth);
+        const points = CreatePolyline(data, left, top, this.Document.color, this.Document.strokeWidth);
         const width = right - left;
         const height = bottom - top;
         const scaleX = this.PanelWidth / width;
@@ -50,7 +52,7 @@ export class InkingStroke extends DocExtendableComponent<FieldViewProps, InkDocu
         return (
             <svg width={width} height={height} style={{
                 transformOrigin: "top left",
-                transform: `translate(${left}px, ${top}px) scale(${scaleX}, ${scaleY})`,
+                transform: `scale(${scaleX}, ${scaleY})`,
                 mixBlendMode: this.Document.tool === InkTool.Highlighter ? "multiply" : "unset",
                 pointerEvents: "all"
             }}>
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 4c8c95529..2a1cc3303 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -9,8 +9,8 @@
 
 .mainContent-div {
     position: relative;
-    width:100%;
-    height:100%;
+    width: 100%;
+    height: 100%;
 }
 
 // add nodes menu. Note that the + button is actually an input label, not an actual button.
@@ -28,6 +28,7 @@
     top: 0;
     left: 0;
     z-index: 1;
+    touch-action: none;
 }
 
 .mainView-mainContent {
@@ -66,7 +67,7 @@
 
 .mainView-libraryFlyout {
     height: 100%;
-    width:100%;
+    width: 100%;
     position: absolute;
     display: flex;
     flex-direction: column;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index a1196ee1c..14c1803c0 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -36,7 +36,7 @@ import { OverlayView } from './OverlayView';
 import PDFMenu from './pdf/PDFMenu';
 import { PreviewCursor } from './PreviewCursor';
 import MarqueeOptionsMenu from './collections/collectionFreeForm/MarqueeOptionsMenu';
-import InkSelectDecorations from './InkSelectDecorations';
+import GestureOverlay from './GestureOverlay';
 import { Scripting } from '../util/Scripting';
 import { AudioBox } from './nodes/AudioBox';
 import { TraceMobx } from '../../new_fields/util';
@@ -510,8 +510,9 @@ export class MainView extends React.Component {
             <SharingManager />
             <GoogleAuthenticationManager />
             <DocumentDecorations />
-            <InkSelectDecorations />
-            {this.mainContent}
+            <GestureOverlay>
+                {this.mainContent}
+            </GestureOverlay>
             <PreviewCursor />
             <ContextMenu />
             <PDFMenu />
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e71e11b48..992820fc7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -153,7 +153,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     createRef = (ele: HTMLDivElement | null) => {
         this._masonryGridRef = ele;
-        this.createDropTarget(ele!); //so the whole grid is the drop target?
+        this.createDropAndGestureTarget(ele!); //so the whole grid is the drop target?
     }
 
     overlays = (doc: Doc) => {
@@ -309,7 +309,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             docList={docList}
             parent={this}
             type={type}
-            createDropTarget={this.createDropTarget}
+            createDropTarget={this.createDropAndGestureTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
         />;
     }
@@ -342,7 +342,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             docList={docList}
             parent={this}
             type={type}
-            createDropTarget={this.createDropTarget}
+            createDropTarget={this.createDropAndGestureTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
             setDocHeight={this.setDocHeight}
         />;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 062521690..73dc7edc6 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -23,6 +23,7 @@ import { basename } from 'path';
 import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
 import { Networking } from "../../Network";
+import { GestureUtils } from "../../../pen-gestures/GestureUtils";
 
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc) => boolean;
@@ -47,15 +48,18 @@ export interface SubCollectionViewProps extends CollectionViewProps {
 export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
     class CollectionSubView extends DocComponent<SubCollectionViewProps, T>(schemaCtor) {
         private dropDisposer?: DragManager.DragDropDisposer;
+        private gestureDisposer?: GestureUtils.GestureEventDisposer;
         private _childLayoutDisposer?: IReactionDisposer;
-        protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+        protected createDropAndGestureTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
             this.dropDisposer && this.dropDisposer();
+            this.gestureDisposer && this.gestureDisposer();
             if (ele) {
                 this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
+                this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this));
             }
         }
         protected CreateDropTarget(ele: HTMLDivElement) { //used in schema view
-            this.createDropTarget(ele);
+            this.createDropAndGestureTarget(ele);
         }
 
         componentDidMount() {
@@ -129,6 +133,11 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             }
         }
 
+        @undoBatch
+        protected onGesture(e: Event, ge: GestureUtils.GestureEvent) {
+
+        }
+
         @undoBatch
         @action
         protected drop(e: Event, de: DragManager.DropEvent): boolean {
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 0b9dc2eb2..2fa6813d7 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -7,9 +7,9 @@
     border-radius: inherit;
     box-sizing: border-box;
     height: 100%;
-    width:100%;
+    width: 100%;
     position: relative;
-    top:0;
+    top: 0;
     padding-left: 10px;
     padding-right: 10px;
     background: $light-color-secondary;
@@ -17,6 +17,7 @@
     overflow: auto;
     user-select: none;
     cursor: default;
+    touch-action: pan-y;
 
     ul {
         list-style: none;
@@ -115,6 +116,7 @@
 .treeViewItem-header {
     border: transparent 1px solid;
     display: flex;
+
     .editableView-container-editing-oneLine {
         min-width: 15px;
     }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eb5a074bb..9656debf3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -272,11 +272,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         return clusterColor;
     }
 
-    @observable private _points: { X: number, Y: number }[] = [];
 
     @action
     onPointerDown = (e: React.PointerEvent): void => {
-        if (e.nativeEvent.cancelBubble) return;
+        if (e.nativeEvent.cancelBubble || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
+            return;
+        }
         this._hitCluster = this.props.Document.useClusters ? this.pickCluster(this.getTransform().transformPoint(e.clientX, e.clientY)) !== -1 : false;
         if (e.button === 0 && !e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) {
             document.removeEventListener("pointermove", this.onPointerMove);
@@ -284,14 +285,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             document.addEventListener("pointermove", this.onPointerMove);
             document.addEventListener("pointerup", this.onPointerUp);
             // if physically using a pen or we're in pen or highlighter mode
-            if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
-                e.stopPropagation();
-                e.preventDefault();
-                const point = this.getTransform().transformPoint(e.pageX, e.pageY);
-                this._points.push({ X: point[0], Y: point[1] });
-            }
+            // if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
+            //     e.stopPropagation();
+            //     e.preventDefault();
+            //     const point = this.getTransform().transformPoint(e.pageX, e.pageY);
+            //     this._points.push({ X: point[0], Y: point[1] });
+            // }
             // if not using a pen and in no ink mode
-            else if (InkingControl.Instance.selectedTool === InkTool.None) {
+            if (InkingControl.Instance.selectedTool === InkTool.None) {
                 this._lastX = e.pageX;
                 this._lastY = e.pageY;
             }
@@ -332,13 +333,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 document.addEventListener("touchmove", this.onTouch);
                 document.removeEventListener("touchend", this.onTouchEnd);
                 document.addEventListener("touchend", this.onTouchEnd);
-                if (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen) {
-                    e.stopPropagation();
-                    e.preventDefault();
-                    const point = this.getTransform().transformPoint(pt.pageX, pt.pageY);
-                    this._points.push({ X: point[0], Y: point[1] });
-                }
-                else if (InkingControl.Instance.selectedTool === InkTool.None) {
+                // if (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen) {
+                //     e.stopPropagation();
+                //     e.preventDefault();
+                //     const point = this.getTransform().transformPoint(pt.pageX, pt.pageY);
+                //     this._points.push({ X: point[0], Y: point[1] });
+                // }
+                if (InkingControl.Instance.selectedTool === InkTool.None) {
                     this._lastX = pt.pageX;
                     this._lastY = pt.pageY;
                     e.stopPropagation();
@@ -352,72 +353,44 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
     }
 
-    @action
-    onPointerUp = (e: PointerEvent): void => {
-        if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) && this._points.length <= 1) return;
-
-        if (this._points.length > 1) {
-            const B = this.svgBounds;
-            const points = this._points.map(p => ({ X: p.X - B.left, Y: p.Y - B.top }));
-
-            const result = GestureUtils.GestureRecognizer.Recognize(new Array(points));
-            let actionPerformed = false;
-            if (result && result.Score > 0.7) {
-                switch (result.Name) {
-                    case GestureUtils.Gestures.Box:
-                        const bounds = { x: Math.min(...this._points.map(p => p.X)), r: Math.max(...this._points.map(p => p.X)), y: Math.min(...this._points.map(p => p.Y)), b: Math.max(...this._points.map(p => p.Y)) };
-                        const sel = this.getActiveDocuments().filter(doc => {
-                            const l = NumCast(doc.x);
-                            const r = l + doc[WidthSym]();
-                            const t = NumCast(doc.y);
-                            const b = t + doc[HeightSym]();
-                            const pass = !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t);
-                            if (pass) {
-                                doc.x = l - B.left - B.width / 2;
-                                doc.y = t - B.top - B.height / 2;
-                            }
-                            return pass;
-                        });
-                        this.addDocument(Docs.Create.FreeformDocument(sel, { x: B.left, y: B.top, width: B.width, height: B.height, panX: 0, panY: 0 }));
-                        sel.forEach(d => this.props.removeDocument(d));
-                        actionPerformed = true;
-                        break;
-                    case GestureUtils.Gestures.Line:
-                        const ep1 = this._points[0];
-                        const ep2 = this._points[this._points.length - 1];
-                        let d1: Doc | undefined;
-                        let d2: Doc | undefined;
-                        this.getActiveDocuments().map(doc => {
-                            const l = NumCast(doc.x);
-                            const r = l + doc[WidthSym]();
-                            const t = NumCast(doc.y);
-                            const b = t + doc[HeightSym]();
-                            if (!d1 && l < ep1.X && r > ep1.X && t < ep1.Y && b > ep1.Y) {
-                                d1 = doc;
-                            }
-                            else if (!d2 && l < ep2.X && r > ep2.X && t < ep2.Y && b > ep2.Y) {
-                                d2 = doc;
-                            }
-                        });
-                        if (d1 && d2) {
-                            if (!LinkManager.Instance.doesLinkExist(d1, d2)) {
-                                DocUtils.MakeLink({ doc: d1 }, { doc: d2 });
-                                actionPerformed = true;
-                            }
-                        }
-                        break;
-                }
-                if (actionPerformed) {
-                    this._points = [];
-                }
-            }
-
-            if (!actionPerformed) {
-                const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { width: B.width, height: B.height, x: B.left, y: B.top });
+    @undoBatch
+    onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
+        switch (ge.gesture) {
+            case GestureUtils.Gestures.Stroke:
+                const points = ge.points;
+                const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
+                const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { x: B.x, y: B.y, width: B.width, height: B.height });
                 this.addDocument(inkDoc);
-                this._points = [];
-            }
+                e.stopPropagation();
+                break;
+            case GestureUtils.Gestures.Box:
+                const lt = this.getTransform().transformPoint(Math.min(...ge.points.map(p => p.X)), Math.min(...ge.points.map(p => p.Y)));
+                const rb = this.getTransform().transformPoint(Math.max(...ge.points.map(p => p.X)), Math.max(...ge.points.map(p => p.Y)));
+                const bounds = { x: lt[0], r: rb[0], y: lt[1], b: rb[1] };
+                const bWidth = bounds.r - bounds.x;
+                const bHeight = bounds.b - bounds.y;
+                const sel = this.getActiveDocuments().filter(doc => {
+                    const l = NumCast(doc.x);
+                    const r = l + doc[WidthSym]();
+                    const t = NumCast(doc.y);
+                    const b = t + doc[HeightSym]();
+                    const pass = !(bounds.x > r || bounds.r < l || bounds.y > b || bounds.b < t);
+                    if (pass) {
+                        doc.x = l - bounds.x - bWidth / 2;
+                        doc.y = t - bounds.y - bHeight / 2;
+                    }
+                    return pass;
+                });
+                this.addDocument(Docs.Create.FreeformDocument(sel, { x: bounds.x, y: bounds.y, width: bWidth, height: bHeight, panX: 0, panY: 0 }));
+                sel.forEach(d => this.props.removeDocument(d));
+                break;
+
         }
+    }
+
+    @action
+    onPointerUp = (e: PointerEvent): void => {
+        if (InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE)) return;
 
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
@@ -473,11 +446,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
         if (!e.cancelBubble) {
             const selectedTool = InkingControl.Instance.selectedTool;
-            if (selectedTool === InkTool.Highlighter || selectedTool === InkTool.Pen || InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
-                const point = this.getTransform().transformPoint(e.clientX, e.clientY);
-                this._points.push({ X: point[0], Y: point[1] });
-            }
-            else if (selectedTool === InkTool.None) {
+            if (selectedTool === InkTool.None) {
                 if (this._hitCluster && this.tryDragCluster(e)) {
                     e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document'  however it does mark the event as cancelBubble=true which we test for in the move event handlers
                     e.preventDefault();
@@ -508,10 +477,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     }
                     this.pan(pt);
                 }
-                else if (InkingControl.Instance.selectedTool !== InkTool.Eraser && InkingControl.Instance.selectedTool !== InkTool.Scrubber) {
-                    const point = this.getTransform().transformPoint(pt.clientX, pt.clientY);
-                    this._points.push({ X: point[0], Y: point[1] });
-                }
             }
             e.stopPropagation();
             e.preventDefault();
@@ -942,34 +907,10 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         ];
     }
 
-    @computed get svgBounds() {
-        const xs = this._points.map(p => p.X);
-        const ys = this._points.map(p => p.Y);
-        const right = Math.max(...xs);
-        const left = Math.min(...xs);
-        const bottom = Math.max(...ys);
-        const top = Math.min(...ys);
-        return { right: right, left: left, bottom: bottom, top: top, width: right - left, height: bottom - top };
-    }
-
-    @computed get currentStroke() {
-        if (this._points.length <= 1) {
-            return (null);
-        }
-
-        const B = this.svgBounds;
-
-        return (
-            <svg width={B.width} height={B.height} style={{ transform: `translate(${B.left}px, ${B.top}px)`, position: "absolute", zIndex: 30000 }}>
-                {CreatePolyline(this._points, B.left, B.top)}
-            </svg>
-        );
-    }
-
     children = () => {
         const eles: JSX.Element[] = [];
         this.extensionDoc && (eles.push(...this.childViews()));
-        this.currentStroke && (eles.push(this.currentStroke));
+        // this.currentStroke && (eles.push(this.currentStroke));
         eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
         return eles;
     }
@@ -998,7 +939,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // otherwise, they are stored in fieldKey.  All annotations to this document are stored in the extension document
         if (!this.extensionDoc) return (null);
         // let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
-        return <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+        return <div className={"collectionfreeformview-container"} ref={this.createDropAndGestureTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
             style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
             onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
             {!this.Document.LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a14f69f71..b544319d7 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -45,6 +45,7 @@ import { InkTool } from '../../../new_fields/InkField';
 import { TraceMobx } from '../../../new_fields/util';
 import { List } from '../../../new_fields/List';
 import { FormattedTextBoxComment } from './FormattedTextBoxComment';
+import { GestureUtils } from '../../../pen-gestures/GestureUtils';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -94,6 +95,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     private _hitTemplateDrag = false;
     private _mainCont = React.createRef<HTMLDivElement>();
     private _dropDisposer?: DragManager.DragDropDisposer;
+    private _gestureEventDisposer?: GestureUtils.GestureEventDisposer;
     private _titleRef = React.createRef<EditableView>();
 
     public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
@@ -107,6 +109,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @action
     componentDidMount() {
         this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
+        this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
 
         !this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.push(this);
     }
@@ -365,10 +368,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         // console.log(e.button)
         // console.log(e.nativeEvent)
         // continue if the event hasn't been canceled AND we are using a moues or this is has an onClick or onDragStart function (meaning it is a button document)
+        if (InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen)) {
+            return;
+        }
         if (!InteractionUtils.IsType(e, InteractionUtils.MOUSETYPE)) {
-            if (!InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
-                e.stopPropagation();
-            }
+            e.stopPropagation();
             return;
         }
         if ((!e.nativeEvent.cancelBubble || this.Document.onClick || this.Document.onDragStart)) {
@@ -424,6 +428,15 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         this._lastTap = Date.now();
     }
 
+    onGesture = (e: Event, ge: GestureUtils.GestureEvent) => {
+        switch (ge.gesture) {
+            case GestureUtils.Gestures.Line:
+                ge.callbackFn && ge.callbackFn(this.props.Document);
+                e.stopPropagation();
+                break;
+        }
+    }
+
     @undoBatch
     deleteClicked = (): void => { SelectionManager.DeselectAll(); this.props.removeDocument && this.props.removeDocument(this.props.Document); }
 
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index 59a85b66b..4edcfa623 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -1,19 +1,43 @@
 import { NDollarRecognizer } from "./ndollar";
 import { Type } from "typescript";
-import { InkField } from "../new_fields/InkField";
+import { InkField, PointData } from "../new_fields/InkField";
 import { Docs } from "../client/documents/Documents";
 import { Doc, WidthSym, HeightSym } from "../new_fields/Doc";
 import { NumCast } from "../new_fields/Types";
 import { CollectionFreeFormView } from "../client/views/collections/collectionFreeForm/CollectionFreeFormView";
+import { Rect } from "react-measure";
 
 export namespace GestureUtils {
     namespace GestureDataTypes {
         export type BoxData = Array<Doc>;
     }
 
+    export class GestureEvent {
+        constructor(
+            readonly gesture: Gestures,
+            readonly points: PointData[],
+            readonly bounds: Rect,
+            readonly callbackFn?: Function
+        ) { }
+    }
+
+    export interface GestureEventDisposer { (): void; }
+
+    export function MakeGestureTarget(
+        element: HTMLElement,
+        func: (e: Event, ge: GestureEvent) => void
+    ): GestureEventDisposer {
+        const handler = (e: Event) => func(e, (e as CustomEvent<GestureEvent>).detail);
+        element.addEventListener("dashOnGesture", handler);
+        return () => {
+            element.removeEventListener("dashOnGesture", handler);
+        }
+    }
+
     export enum Gestures {
         Box = "box",
-        Line = "line"
+        Line = "line",
+        Stroke = "stroke"
     }
 
     export const GestureRecognizer = new NDollarRecognizer(false);
-- 
cgit v1.2.3-70-g09d2


From 596d30bc3f755eaafd413ced7613ace6735458fa Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Fri, 10 Jan 2020 16:05:00 -0500
Subject: better working version of pivot viewer

---
 package-lock.json                                  | 7069 ++++++++++----------
 package.json                                       |    2 +-
 src/client/util/DropConverter.ts                   |    8 +-
 src/client/views/TemplateMenu.tsx                  |    2 +-
 .../views/collections/CollectionSchemaView.tsx     |    2 -
 .../views/collections/CollectionStackingView.tsx   |    4 +-
 .../views/collections/CollectionTreeView.tsx       |   17 +-
 .../views/collections/CollectionViewChromes.tsx    |    6 +-
 .../CollectionFreeFormLayoutEngines.tsx            |   13 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   21 +-
 .../views/nodes/CollectionFreeFormDocumentView.tsx |   11 +
 .../views/nodes/ContentFittingDocumentView.tsx     |    2 -
 src/client/views/nodes/DocumentBox.tsx             |    2 -
 src/client/views/nodes/FormattedTextBoxComment.tsx |    1 -
 .../views/presentationview/PresElementBox.tsx      |    1 -
 src/client/views/search/SearchItem.tsx             |    2 -
 src/new_fields/Doc.ts                              |    8 +-
 17 files changed, 3603 insertions(+), 3568 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/package-lock.json b/package-lock.json
index cf61e6aab..c4f0446bc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
             "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
             "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
             "requires": {
-                "@babel/highlight": "^7.0.0"
+                "@babel/highlight": "7.5.0"
             }
         },
         "@babel/helper-module-imports": {
@@ -17,7 +17,7 @@
             "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz",
             "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==",
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "7.7.4"
             }
         },
         "@babel/highlight": {
@@ -25,9 +25,9 @@
             "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
             "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
             "requires": {
-                "chalk": "^2.0.0",
-                "esutils": "^2.0.2",
-                "js-tokens": "^4.0.0"
+                "chalk": "2.4.2",
+                "esutils": "2.0.2",
+                "js-tokens": "4.0.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -35,7 +35,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -43,9 +43,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -53,7 +53,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -63,7 +63,7 @@
             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz",
             "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==",
             "requires": {
-                "regenerator-runtime": "^0.13.2"
+                "regenerator-runtime": "0.13.3"
             }
         },
         "@babel/types": {
@@ -71,9 +71,9 @@
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
             "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
             "requires": {
-                "esutils": "^2.0.2",
-                "lodash": "^4.17.13",
-                "to-fast-properties": "^2.0.0"
+                "esutils": "2.0.2",
+                "lodash": "4.17.15",
+                "to-fast-properties": "2.0.0"
             }
         },
         "@emotion/cache": {
@@ -106,7 +106,7 @@
                 "@emotion/memoize": "0.7.3",
                 "@emotion/unitless": "0.7.4",
                 "@emotion/utils": "0.11.2",
-                "csstype": "^2.5.7"
+                "csstype": "2.6.6"
             }
         },
         "@emotion/sheet": {
@@ -144,7 +144,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-solid/-/fontawesome-free-solid-5.0.13.tgz",
             "integrity": "sha512-b+krVnqkdDt52Yfev0x0ZZgtxBQsLw00Zfa3uaVWIDzpNZVtrEXuxldUSUaN/ihgGhSNi8VpvDAdNPVgCKOSxw==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.1.7"
+                "@fortawesome/fontawesome-common-types": "0.1.7"
             }
         },
         "@fortawesome/fontawesome-svg-core": {
@@ -152,7 +152,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.19.tgz",
             "integrity": "sha512-D4ICXg9oU08eF9o7Or392gPpjmwwgJu8ecCFusthbID95CLVXOgIyd4mOKD9Nud5Ckz+Ty59pqkNtThDKR0erA==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.19"
+                "@fortawesome/fontawesome-common-types": "0.2.19"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -167,7 +167,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.9.0.tgz",
             "integrity": "sha512-sOz1wFyslaHUak8tY6IEhSAV1mAWbCLssBR8yFQV6f065k8nUCkjyrcxW4RVl9+wiLXmeG1CJUABUJV9DiW+7Q==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.19"
+                "@fortawesome/fontawesome-common-types": "0.2.19"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -182,7 +182,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.9.0.tgz",
             "integrity": "sha512-6ZO0jLhk/Yrso0u5pXeYYSfZiHCNoCF7SgtqStdlEX8WtWD4IOfAB1N+MlSnMo12P5KR4cmucX/K0NCOPrhJwg==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.19"
+                "@fortawesome/fontawesome-common-types": "0.2.19"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -197,7 +197,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.9.0.tgz",
             "integrity": "sha512-U8YXPfWcSozsCW0psCtlRGKjjRs5+Am5JJwLOUmVHFZbIEWzaz4YbP84EoPwUsVmSAKrisu3QeNcVOtmGml0Xw==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.19"
+                "@fortawesome/fontawesome-common-types": "0.2.19"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -212,8 +212,8 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.4.tgz",
             "integrity": "sha512-GwmxQ+TK7PEdfSwvxtGnMCqrfEm0/HbRHArbUudsYiy9KzVCwndxa2KMcfyTQ8El0vROrq8gOOff09RF1oQe8g==",
             "requires": {
-                "humps": "^2.0.1",
-                "prop-types": "^15.5.10"
+                "humps": "2.0.1",
+                "prop-types": "15.7.2"
             }
         },
         "@hig/flyout": {
@@ -221,10 +221,10 @@
             "resolved": "https://registry.npmjs.org/@hig/flyout/-/flyout-1.2.0.tgz",
             "integrity": "sha512-/maJI6COH1UyUX3LCa0muG2VmPiXBtacyz8RAdLLcDIgeTpmyvxpb0FFZI/ib2HUbO2iILBN7qnXiMJ4YNJ/bQ==",
             "requires": {
-                "@hig/utils": "^0.4.0",
-                "emotion": "^10.0.0",
-                "prop-types": "^15.7.1",
-                "react-transition-group": "^2.3.1"
+                "@hig/utils": "0.4.0",
+                "emotion": "10.0.23",
+                "prop-types": "15.7.2",
+                "react-transition-group": "2.9.0"
             }
         },
         "@hig/theme-context": {
@@ -232,8 +232,8 @@
             "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.3.tgz",
             "integrity": "sha512-c0Ju+Z8C532ZZtjwOLzN+XeO+pL3kqUawu6ZG3J084MH5RM9W8JCKyMf4D9Qr38jFWoiX6u8yiSxxjV/mz9Sqw==",
             "requires": {
-                "create-react-context": "^0.2.3",
-                "prop-types": "^15.6.1"
+                "create-react-context": "0.2.3",
+                "prop-types": "15.7.2"
             }
         },
         "@hig/theme-data": {
@@ -241,7 +241,7 @@
             "resolved": "https://registry.npmjs.org/@hig/theme-data/-/theme-data-2.8.0.tgz",
             "integrity": "sha512-wH82aJXlFTAE0HZrjCsRfVA8yDHjAve9Sr9lADQcQ4UQTjDHJVGN5Ed7FcPEWqV6kriCSK7JYuRhi52bbDOflw==",
             "requires": {
-                "tinycolor2": "^1.4.1"
+                "tinycolor2": "1.4.1"
             }
         },
         "@hig/utils": {
@@ -249,8 +249,8 @@
             "resolved": "https://registry.npmjs.org/@hig/utils/-/utils-0.4.0.tgz",
             "integrity": "sha512-EQnMGZKdPh9UJaBUKLKXp92sSoCo+PTpgrGNd8q+71uRFdD0udMu/+yeVekTEtNOJcCk1gnKfyg1rRvIbTcpRw==",
             "requires": {
-                "emotion": "^10.0.0",
-                "lodash.memoize": "^4.1.2"
+                "emotion": "10.0.23",
+                "lodash.memoize": "4.1.2"
             }
         },
         "@icons/material": {
@@ -268,12 +268,12 @@
             "resolved": "https://registry.npmjs.org/@react-bootstrap/react-popper/-/react-popper-1.2.1.tgz",
             "integrity": "sha512-4l3q7LcZEhrSkI4d3Ie3g4CdrXqqTexXX4PFT45CB0z5z2JUbaxgRwKNq7r5j2bLdVpZm+uvUGqxJw8d9vgbJQ==",
             "requires": {
-                "babel-runtime": "6.x.x",
-                "create-react-context": "^0.2.1",
-                "popper.js": "^1.14.4",
-                "prop-types": "^15.6.1",
-                "typed-styles": "^0.0.5",
-                "warning": "^3.0.0"
+                "babel-runtime": "6.26.0",
+                "create-react-context": "0.2.3",
+                "popper.js": "1.15.0",
+                "prop-types": "15.7.2",
+                "typed-styles": "0.0.5",
+                "warning": "3.0.0"
             }
         },
         "@restart/context": {
@@ -291,8 +291,8 @@
             "resolved": "https://registry.npmjs.org/@trendmicro/react-buttons/-/react-buttons-1.3.1.tgz",
             "integrity": "sha512-9zvt/fdkqCb9kxUdZnvTZKmbmykM2wDQ3VEJFtztGcKAkm4Wkq4oZOQLJXKfUQ1vX3w+YDJob18LkNOzaHI1UQ==",
             "requires": {
-                "classnames": "^2.2.5",
-                "prop-types": "^15.5.8"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2"
             }
         },
         "@trendmicro/react-dropdown": {
@@ -300,13 +300,13 @@
             "resolved": "https://registry.npmjs.org/@trendmicro/react-dropdown/-/react-dropdown-1.3.0.tgz",
             "integrity": "sha512-KwL0ksEZPay7qNsiGcPQ3aGmyfJCcUuIjiD9HZs6L66ScwSRoFkDlAjMTlRVLFcYVNhpuyUH4pPiFlKQQzDHGQ==",
             "requires": {
-                "@trendmicro/react-buttons": "^1.3.0",
-                "chained-function": "^0.5.0",
-                "classnames": "^2.2.5",
-                "dom-helpers": "^3.3.1",
-                "prop-types": "^15.6.0",
-                "uncontrollable": "^5.0.0",
-                "warning": "^3.0.0"
+                "@trendmicro/react-buttons": "1.3.1",
+                "chained-function": "0.5.0",
+                "classnames": "2.2.6",
+                "dom-helpers": "3.4.0",
+                "prop-types": "15.7.2",
+                "uncontrollable": "5.1.0",
+                "warning": "3.0.0"
             }
         },
         "@types/adm-zip": {
@@ -314,7 +314,7 @@
             "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.32.tgz",
             "integrity": "sha512-hv1O7ySn+XvP5OeDQcJFWwVb2v+GFGO1A9aMTQ5B/bzxb7WW21O8iRhVdsKKr8QwuiagzGmPP+gsUAYZ6bRddQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/animejs": {
@@ -332,7 +332,7 @@
             "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-3.0.0.tgz",
             "integrity": "sha512-orghAMOF+//wSg4ru2znk6jt0eIPvKTtMVLH7XcYcjbcRyAXRClDlh27QVdqnAvVM37yu9xDP6Nh7egRhNr8tQ==",
             "requires": {
-                "@types/glob": "*"
+                "@types/glob": "7.1.1"
             }
         },
         "@types/async": {
@@ -350,7 +350,7 @@
             "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
             "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
             "requires": {
-                "@types/babel-types": "*"
+                "@types/babel-types": "7.0.7"
             }
         },
         "@types/bcrypt-nodejs": {
@@ -368,8 +368,8 @@
             "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.0.tgz",
             "integrity": "sha512-a2+YeUjPkztKJu5aIF2yArYFQQp8d51wZ7DavSHjFuY1mqVgidGyzEQ41JIVNy82fXj8yPgy2vJmfIywgESW6w==",
             "requires": {
-                "@types/connect": "*",
-                "@types/node": "*"
+                "@types/connect": "3.4.32",
+                "@types/node": "10.14.13"
             }
         },
         "@types/bson": {
@@ -377,7 +377,7 @@
             "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.0.tgz",
             "integrity": "sha512-pq/rqJwJWkbS10crsG5bgnrisL8pML79KlMKQMoQwLUjlPAkrUHMvHJ3oGwE7WHR61Lv/nadMwXVAD2b+fpD8Q==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/caseless": {
@@ -401,7 +401,7 @@
             "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.0.tgz",
             "integrity": "sha512-5qqtNia+m2I0/85+pd2YzAXaTyKO8j+svirO5aN+XaQJ5+eZ8nx0jPtEWZLxCi50xwYsX10xUHetFzfb1WEs4Q==",
             "requires": {
-                "@types/color-convert": "*"
+                "@types/color-convert": "1.9.0"
             }
         },
         "@types/color-convert": {
@@ -409,7 +409,7 @@
             "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-1.9.0.tgz",
             "integrity": "sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg==",
             "requires": {
-                "@types/color-name": "*"
+                "@types/color-name": "1.1.1"
             }
         },
         "@types/color-name": {
@@ -422,7 +422,7 @@
             "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
             "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/connect-flash": {
@@ -430,7 +430,7 @@
             "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.34.tgz",
             "integrity": "sha512-QC93TwnTZ0sk//bfT81o7U4GOedbOZAcgvqi0v1vJqCESC8tqIVnhzB1CHiAUBUWFjoxG5JQF0TYaNa6DMb6Ig==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.0"
             }
         },
         "@types/cookie-parser": {
@@ -438,7 +438,7 @@
             "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.1.tgz",
             "integrity": "sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.0"
             }
         },
         "@types/cookie-session": {
@@ -446,8 +446,8 @@
             "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.37.tgz",
             "integrity": "sha512-h8uZLDGyfAgER6kHbHlYWm1g/P/7zCBMOW6yT5/fQydVJxByJD4tohSvHBzJrGoLVmQJefQdfwuNkKb23cq29Q==",
             "requires": {
-                "@types/express": "*",
-                "@types/keygrip": "*"
+                "@types/express": "4.17.0",
+                "@types/keygrip": "1.0.1"
             }
         },
         "@types/d3-format": {
@@ -460,7 +460,7 @@
             "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
             "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/events": {
@@ -473,7 +473,7 @@
             "resolved": "https://registry.npmjs.org/@types/exif/-/exif-0.6.0.tgz",
             "integrity": "sha512-TyXIoevHn10FjPnCbNfpFlgb44c5KPsCbdWaNf59T76fKOl6YWfBQTmlt84kI7GtY4VuG9aW0qlEEmMuNDldoQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/express": {
@@ -481,9 +481,9 @@
             "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.0.tgz",
             "integrity": "sha512-CjaMu57cjgjuZbh9DpkloeGxV45CnMGlVd+XpG7Gm9QgVrd7KFq+X4HY0vM+2v0bczS48Wg7bvnMY5TN+Xmcfw==",
             "requires": {
-                "@types/body-parser": "*",
-                "@types/express-serve-static-core": "*",
-                "@types/serve-static": "*"
+                "@types/body-parser": "1.17.0",
+                "@types/express-serve-static-core": "4.16.7",
+                "@types/serve-static": "1.13.2"
             }
         },
         "@types/express-flash": {
@@ -491,8 +491,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.0.tgz",
             "integrity": "sha512-zs1xXRIZOjghUBriJPSnhPmfDpqf/EQxT21ggi/9XZ9/RHYrUi+5vK2jnQrP2pD1abbuZvm7owLICiNCLBQzEQ==",
             "requires": {
-                "@types/connect-flash": "*",
-                "@types/express": "*"
+                "@types/connect-flash": "0.0.34",
+                "@types/express": "4.17.0"
             }
         },
         "@types/express-serve-static-core": {
@@ -500,8 +500,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.16.7.tgz",
             "integrity": "sha512-847KvL8Q1y3TtFLRTXcVakErLJQgdpFSaq+k043xefz9raEf0C7HalpSY7OW5PyjCnY8P7bPW5t/Co9qqp+USg==",
             "requires": {
-                "@types/node": "*",
-                "@types/range-parser": "*"
+                "@types/node": "10.14.13",
+                "@types/range-parser": "1.2.3"
             }
         },
         "@types/express-session": {
@@ -509,8 +509,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.15.13.tgz",
             "integrity": "sha512-BLRzO/ZfjTTLSRakUJxB0p5I5NmBHuyHkXDyh8sezdCMYxpqXrvMljKwle81I9AeCAzdq6nfz6qafmYLQ/rU9A==",
             "requires": {
-                "@types/express": "*",
-                "@types/node": "*"
+                "@types/express": "4.17.0",
+                "@types/node": "10.14.13"
             }
         },
         "@types/express-validator": {
@@ -518,7 +518,7 @@
             "resolved": "https://registry.npmjs.org/@types/express-validator/-/express-validator-3.0.0.tgz",
             "integrity": "sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ==",
             "requires": {
-                "express-validator": "*"
+                "express-validator": "5.3.1"
             }
         },
         "@types/formidable": {
@@ -526,8 +526,8 @@
             "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz",
             "integrity": "sha512-dIhM5t8lRP0oWe2HF8MuPvdd1TpPTjhDMAqemcq6oIZQCBQTovhBAdTQ5L5veJB4pdQChadmHuxtB0YzqvfU3Q==",
             "requires": {
-                "@types/events": "*",
-                "@types/node": "*"
+                "@types/events": "3.0.0",
+                "@types/node": "10.14.13"
             }
         },
         "@types/gapi": {
@@ -540,9 +540,9 @@
             "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
             "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
             "requires": {
-                "@types/events": "*",
-                "@types/minimatch": "*",
-                "@types/node": "*"
+                "@types/events": "3.0.0",
+                "@types/minimatch": "3.0.3",
+                "@types/node": "10.14.13"
             }
         },
         "@types/jquery": {
@@ -550,7 +550,7 @@
             "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.30.tgz",
             "integrity": "sha512-chB+QbLulamShZAFcTJtl8opZwHFBpDOP6nRLrPGkhC6N1aKWrDXg2Nc71tEg6ny6E8SQpRwbWSi9GdstH5VJA==",
             "requires": {
-                "@types/sizzle": "*"
+                "@types/sizzle": "2.3.2"
             }
         },
         "@types/jquery-awesome-cursor": {
@@ -558,7 +558,7 @@
             "resolved": "https://registry.npmjs.org/@types/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.0.tgz",
             "integrity": "sha512-tNou39eBTgyQtQGzcynUblExZdZiDqg5xuorANsoIfwBRBZZpHOP8wT/iDSR/qSq2rsu1KuQEfoC8z2L9YSp8A==",
             "requires": {
-                "@types/jquery": "*"
+                "@types/jquery": "3.3.30"
             }
         },
         "@types/jsonwebtoken": {
@@ -566,7 +566,7 @@
             "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.2.tgz",
             "integrity": "sha512-Mkjljd9DTpkPlrmGfTJvcP4aBU7yO2QmW7wNVhV4/6AEUxYoacqU7FJU/N0yFEHTsIrE4da3rUrjrR5ejicFmA==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/keygrip": {
@@ -585,7 +585,7 @@
             "integrity": "sha512-j5AcZo7dbMxHoOimcHEIh0JZe5e1b8q8AqGSpZJrYc7xOgCIP79cIjTdx5jSDLtySnQDwkDTqwlC7Xw7uXw7qg==",
             "dev": true,
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/mime": {
@@ -603,7 +603,7 @@
             "resolved": "https://registry.npmjs.org/@types/mobile-detect/-/mobile-detect-1.3.4.tgz",
             "integrity": "sha512-MGBTvT5c7aH8eX6szFYP3dWPryNLt5iGlo31XNaJtt8o6jsg6tjn99eEMq9l8T6cPZymsr+J4Jth8+/G/04ZDw==",
             "requires": {
-                "mobile-detect": "*"
+                "mobile-detect": "1.4.3"
             }
         },
         "@types/mocha": {
@@ -617,8 +617,8 @@
             "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.1.29.tgz",
             "integrity": "sha512-X74BBsFQruQXVJif2oJ08uceUfAVSkb2gl6Zm07fgqKQHnTdxIW3vknHNpQahogezX42EPQv9A+dYG0+CFY8aA==",
             "requires": {
-                "@types/bson": "*",
-                "@types/node": "*"
+                "@types/bson": "4.0.0",
+                "@types/node": "10.14.13"
             }
         },
         "@types/mongoose": {
@@ -626,8 +626,8 @@
             "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.5.9.tgz",
             "integrity": "sha512-KVM8yWVGPc2XD8iov+VzMq/3vyzJ3kqQuiZOJOe3VTVW+U7R4bk5lDfRFvqnnPpQ/pvMPSn6xVVnuYaMUKhZSg==",
             "requires": {
-                "@types/mongodb": "*",
-                "@types/node": "*"
+                "@types/mongodb": "3.1.29",
+                "@types/node": "10.14.13"
             }
         },
         "@types/node": {
@@ -640,7 +640,7 @@
             "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.8.tgz",
             "integrity": "sha512-IX1P3bxDP1VIdZf6/kIWYNmSejkYm9MOyMEtoDFi4DVzKjJ3kY4GhOcOAKs6lZRjqVVmF9UjPOZXuQczlpZThw==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/oauth": {
@@ -648,7 +648,7 @@
             "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz",
             "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/orderedmap": {
@@ -666,7 +666,7 @@
             "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.2.tgz",
             "integrity": "sha512-Pf39AYKf8q+YoONym3150cEwfUD66dtwHJWvbeOzKxnA0GZZ/vAXhNWv9vMhKyRQBQZiQyWQnhYBEBlKW6G8wg==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.0"
             }
         },
         "@types/passport-google-oauth20": {
@@ -674,9 +674,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.2.tgz",
             "integrity": "sha512-5Pek3WNGb/Qb466DJMY26VeuT/WSExJYYOSVlk0hWXZRH4hAjTKxVq2ljXv2TLkTlDEgwi8KOdPpiuT67qjWJQ==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*",
-                "@types/passport-oauth2": "*"
+                "@types/express": "4.17.0",
+                "@types/passport": "1.0.2",
+                "@types/passport-oauth2": "1.4.8"
             }
         },
         "@types/passport-local": {
@@ -684,9 +684,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
             "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*",
-                "@types/passport-strategy": "*"
+                "@types/express": "4.17.0",
+                "@types/passport": "1.0.2",
+                "@types/passport-strategy": "0.2.35"
             }
         },
         "@types/passport-oauth2": {
@@ -694,9 +694,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.8.tgz",
             "integrity": "sha512-tlX16wyFE5YJR2pHpZ308dgB1MV9/Ra2wfQh71eWk+/umPoD1Rca2D4N5M27W7nZm1wqUNGTk1I864nHvEgiFA==",
             "requires": {
-                "@types/express": "*",
-                "@types/oauth": "*",
-                "@types/passport": "*"
+                "@types/express": "4.17.0",
+                "@types/oauth": "0.9.1",
+                "@types/passport": "1.0.2"
             }
         },
         "@types/passport-strategy": {
@@ -704,8 +704,8 @@
             "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
             "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*"
+                "@types/express": "4.17.0",
+                "@types/passport": "1.0.2"
             }
         },
         "@types/pdfjs-dist": {
@@ -723,9 +723,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-commands/-/prosemirror-commands-1.0.1.tgz",
             "integrity": "sha512-GeE12m8VT9N1JrzoY//946IX8ZyQOLNmvryJ+BNQs/HvhmXW9EWOcWUE6OBRtxK7Y8SrzSOwx4XmqSgVmK3tGQ==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.9.0"
             }
         },
         "@types/prosemirror-history": {
@@ -733,8 +733,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
             "integrity": "sha512-BYyPJlWDo3VEnWS5X2DCHXrrAKEjdbCe1DUjGL6R/8hmwMFe3iMJGYdBkOXU1FfkTpw7Z+PlwY/pMyeelVydmg==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-inputrules": {
@@ -742,8 +742,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
             "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-keymap": {
@@ -751,8 +751,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
             "integrity": "sha512-8IjM8ySmoZps9Tn+aKfB4ZR6zoNOjeQfAc9YLQujYXHJB6tdGWV0cbTuoT4QmZOR1iecN1EJ6E9RiRUBk796kQ==",
             "requires": {
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.9.0"
             }
         },
         "@types/prosemirror-menu": {
@@ -760,9 +760,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-menu/-/prosemirror-menu-1.0.1.tgz",
             "integrity": "sha512-wVGc6G7uYRvjIuVwV0zKSLwntFH1wanFwM1fDkq2YcUrLhuj4zZ1i7IPe+yqSoPm7JfmjiDEgHXTpafmwLKJrA==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.9.0"
             }
         },
         "@types/prosemirror-model": {
@@ -770,7 +770,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-model/-/prosemirror-model-1.7.2.tgz",
             "integrity": "sha512-2l+yXvidg3AUHN07mO4Jd8Q84fo6ksFsy7LHUurLYrZ74uTahBp2fzcO49AKZMzww2EulXJ40Kl/OFaQ/7A1fw==",
             "requires": {
-                "@types/orderedmap": "*"
+                "@types/orderedmap": "1.0.0"
             }
         },
         "@types/prosemirror-schema-basic": {
@@ -778,7 +778,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-basic/-/prosemirror-schema-basic-1.0.1.tgz",
             "integrity": "sha512-IOQAYf1urifbH+Zwbq5XfFOUMNCbEnvIqpuSAE8SUt00nDAoH62T/S8Qhu8LuF++KQbyXb7fdMp352zkPW9Hmw==",
             "requires": {
-                "@types/prosemirror-model": "*"
+                "@types/prosemirror-model": "1.7.2"
             }
         },
         "@types/prosemirror-schema-list": {
@@ -786,9 +786,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz",
             "integrity": "sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA==",
             "requires": {
-                "@types/orderedmap": "*",
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/orderedmap": "1.0.0",
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-state": {
@@ -796,9 +796,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.2.3.tgz",
             "integrity": "sha512-6m433Hubix9bx+JgcLW7zzyiZuzwjq5mBdSMYY4Yi5c5ZpV2RiVmg7Cy6f9Thtts8vuztilw+PczJAgDm1Frfw==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-transform": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-transform": "1.1.0",
+                "@types/prosemirror-view": "1.9.0"
             }
         },
         "@types/prosemirror-transform": {
@@ -806,7 +806,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-transform/-/prosemirror-transform-1.1.0.tgz",
             "integrity": "sha512-VsPiEj+88Xvw8f0vXHL65z2qHlnrvnybW9GC7w9I9PORcKheDi7hQBgP8JdDwUPG7ttyUYUaSAec0TV6DsdWKg==",
             "requires": {
-                "@types/prosemirror-model": "*"
+                "@types/prosemirror-model": "1.7.2"
             }
         },
         "@types/prosemirror-view": {
@@ -814,9 +814,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-view/-/prosemirror-view-1.9.0.tgz",
             "integrity": "sha512-57Z7VoQxGdlazRPnRmNqpl9jD8HoNhWu9hpAIyPAvF/4u2Mte0S/LJQQgb9zNmmzug5cbnEk1dBY6gjwDGDeeQ==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-transform": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-transform": "1.1.0"
             }
         },
         "@types/pug": {
@@ -834,7 +834,7 @@
             "resolved": "https://registry.npmjs.org/@types/rc-switch/-/rc-switch-1.8.0.tgz",
             "integrity": "sha512-3zvdN04uILIa788Sdl4VVxkkcge/cSIuHgVDeMJ6NxDBPtPiva3CYd8QEVsD6+u1NcNCLVlpn96cGSW6NJcUrQ==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/react": {
@@ -842,8 +842,8 @@
             "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.23.tgz",
             "integrity": "sha512-abkEOIeljniUN9qB5onp++g0EY38h7atnDHxwKUFz1r3VH1+yG1OKi2sNPTyObL40goBmfKFpdii2lEzwLX1cA==",
             "requires": {
-                "@types/prop-types": "*",
-                "csstype": "^2.2.0"
+                "@types/prop-types": "15.7.1",
+                "csstype": "2.6.6"
             }
         },
         "@types/react-autosuggest": {
@@ -851,7 +851,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-autosuggest/-/react-autosuggest-9.3.9.tgz",
             "integrity": "sha512-MuDqgOZmbcT4Uzj4boMY3icf90dlvPTFZ1nnXHYaRKmk7ZPG7srI/In1lTxUvZsgoS+WAbz2CIEKAktCXfJmwg==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/react-color": {
@@ -859,7 +859,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-2.17.2.tgz",
             "integrity": "sha512-6aa8L1hhxxjEZz7LY45NRMOKUt72dVrB3MWXESv92YZohH3n2jjUi7j1cMeygdSUxZD8qLU5ITA63tRYYu8M2g==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/react-dom": {
@@ -868,7 +868,7 @@
             "integrity": "sha512-eIRpEW73DCzPIMaNBDP5pPIpK1KXyZwNgfxiVagb5iGiz6da+9A5hslSX6GAQKdO7SayVCS/Fr2kjqprgAvkfA==",
             "dev": true,
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/react-measure": {
@@ -876,7 +876,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.5.tgz",
             "integrity": "sha512-T1Bpt8FlWbDhoInUaNrjTOiVRpRJmrRcqhFJxLGBq1VjaqBLHCvUPapgdKMWEIX4Oqsa1SSKjtNkNJGy6WAAZg==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/react-table": {
@@ -884,7 +884,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.5.tgz",
             "integrity": "sha512-ueCsAadG1IwuuAZM+MWf2SoxbccSWweyQa9YG6xGN5cOVK3SayPOJW4MsUHGpY0V/Q+iZWgohpasliiao29O6g==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.8.23"
             }
         },
         "@types/request": {
@@ -892,10 +892,10 @@
             "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.2.tgz",
             "integrity": "sha512-gP+PSFXAXMrd5PcD7SqHeUjdGshAI8vKQ3+AvpQr3ht9iQea+59LOKvKITcQI+Lg+1EIkDP6AFSBUJPWG8GDyA==",
             "requires": {
-                "@types/caseless": "*",
-                "@types/node": "*",
-                "@types/tough-cookie": "*",
-                "form-data": "^2.5.0"
+                "@types/caseless": "0.12.2",
+                "@types/node": "10.14.13",
+                "@types/tough-cookie": "2.3.5",
+                "form-data": "2.5.0"
             }
         },
         "@types/request-promise": {
@@ -903,8 +903,8 @@
             "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.44.tgz",
             "integrity": "sha512-RId7eFsUKxfal1LirDDIcOp9u3MM3NXFDBcC3sqIMcmu7f4U6DsCEMD8RbLZtnPrQlN5Jc79di/WPsIEDO4keg==",
             "requires": {
-                "@types/bluebird": "*",
-                "@types/request": "*"
+                "@types/bluebird": "3.5.27",
+                "@types/request": "2.48.2"
             }
         },
         "@types/rimraf": {
@@ -912,8 +912,8 @@
             "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.3.tgz",
             "integrity": "sha512-dZfyfL/u9l/oi984hEXdmAjX3JHry7TLWw43u1HQ8HhPv6KtfxnrZ3T/bleJ0GEvnk9t5sM7eePkgMqz3yBcGg==",
             "requires": {
-                "@types/glob": "*",
-                "@types/node": "*"
+                "@types/glob": "7.1.1",
+                "@types/node": "10.14.13"
             }
         },
         "@types/serve-static": {
@@ -921,8 +921,8 @@
             "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.2.tgz",
             "integrity": "sha512-/BZ4QRLpH/bNYgZgwhKEh+5AsboDBcUdlBYgzoLX0fpj3Y2gp6EApyOlM3bK53wQS/OE1SrdSYBAbux2D1528Q==",
             "requires": {
-                "@types/express-serve-static-core": "*",
-                "@types/mime": "*"
+                "@types/express-serve-static-core": "4.16.7",
+                "@types/mime": "2.0.1"
             }
         },
         "@types/sharp": {
@@ -930,7 +930,7 @@
             "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.22.2.tgz",
             "integrity": "sha512-oH49f42h3nf/qys0weYsaTGiMv67wPB769ynCoPfBAVwjjxFF3QtIPEe3MfhwyNjQAhQhTEfnmMKvVZfcFkhIw==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/shelljs": {
@@ -938,8 +938,8 @@
             "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.5.tgz",
             "integrity": "sha512-bZgjwIWu9gHCjirKJoOlLzGi5N0QgZ5t7EXEuoqyWCHTuSddURXo3FOBYDyRPNOWzZ6NbkLvZnVkn483Y/tvcQ==",
             "requires": {
-                "@types/glob": "*",
-                "@types/node": "*"
+                "@types/glob": "7.1.1",
+                "@types/node": "10.14.13"
             }
         },
         "@types/sizzle": {
@@ -952,7 +952,7 @@
             "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.2.tgz",
             "integrity": "sha512-Ind+4qMNfQ62llyB4IMs1D8znMEBsMKohZBPqfBUIXqLQ9bdtWIbNTBWwtdcBWJKnokMZGcmWOOKslatni5vtA==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/socket.io-client": {
@@ -987,7 +987,7 @@
             "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz",
             "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=",
             "requires": {
-                "typescript": "*"
+                "typescript": "3.7.2"
             }
         },
         "@types/uglify-js": {
@@ -995,7 +995,7 @@
             "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
             "integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
             "requires": {
-                "source-map": "^0.6.1"
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -1010,7 +1010,7 @@
             "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.5.tgz",
             "integrity": "sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.14.13"
             }
         },
         "@types/webpack": {
@@ -1018,11 +1018,11 @@
             "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.32.0.tgz",
             "integrity": "sha512-kpz5wHDyG/WEpzX9gcwFp/w0oSsq0n/rmFdJelk/QBMHmNIOZdiTDInV0Lj8itGKBahQrBgJGJRss/6UHgLuKg==",
             "requires": {
-                "@types/anymatch": "*",
-                "@types/node": "*",
-                "@types/tapable": "*",
-                "@types/uglify-js": "*",
-                "source-map": "^0.6.0"
+                "@types/anymatch": "1.3.1",
+                "@types/node": "10.14.13",
+                "@types/tapable": "1.0.4",
+                "@types/uglify-js": "3.0.4",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -1038,10 +1038,10 @@
             "integrity": "sha512-DzNJJ6ah/6t1n8sfAgQyEbZ/OMmFcF9j9P3aesnm7G6/iBFR/qiGin8K89J0RmaWIBzhTMdDg3I5PmKmSv7N9w==",
             "dev": true,
             "requires": {
-                "@types/connect": "*",
-                "@types/memory-fs": "*",
-                "@types/webpack": "*",
-                "loglevel": "^1.6.2"
+                "@types/connect": "3.4.32",
+                "@types/memory-fs": "0.3.2",
+                "@types/webpack": "4.32.0",
+                "loglevel": "1.6.3"
             }
         },
         "@types/webpack-hot-middleware": {
@@ -1050,8 +1050,8 @@
             "integrity": "sha512-41qSQeyRGZkWSi366jMQVsLo5fdLT8EgmvHNoBwcCtwZcHrQk6An6tD+ZfC0zMdNHzVEFlzQvT2mTte8zDxqNw==",
             "dev": true,
             "requires": {
-                "@types/connect": "*",
-                "@types/webpack": "*"
+                "@types/connect": "3.4.32",
+                "@types/webpack": "4.32.0"
             }
         },
         "@types/youtube": {
@@ -1110,7 +1110,7 @@
             "dev": true,
             "requires": {
                 "@webassemblyjs/ast": "1.8.5",
-                "mamacro": "^0.0.3"
+                "mamacro": "0.0.3"
             }
         },
         "@webassemblyjs/helper-wasm-bytecode": {
@@ -1137,7 +1137,7 @@
             "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
             "dev": true,
             "requires": {
-                "@xtuc/ieee754": "^1.2.0"
+                "@xtuc/ieee754": "1.2.0"
             }
         },
         "@webassemblyjs/leb128": {
@@ -1263,7 +1263,7 @@
             "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
             "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
             "requires": {
-                "event-target-shim": "^5.0.0"
+                "event-target-shim": "5.0.1"
             }
         },
         "accepts": {
@@ -1271,7 +1271,7 @@
             "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
             "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
             "requires": {
-                "mime-types": "~2.1.24",
+                "mime-types": "2.1.24",
                 "negotiator": "0.6.2"
             }
         },
@@ -1285,7 +1285,7 @@
             "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
             "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
             "requires": {
-                "acorn": "^4.0.4"
+                "acorn": "4.0.13"
             },
             "dependencies": {
                 "acorn": {
@@ -1300,7 +1300,7 @@
             "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz",
             "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==",
             "requires": {
-                "acorn": "^5.0.3"
+                "acorn": "5.7.3"
             }
         },
         "acorn-walk": {
@@ -1324,7 +1324,7 @@
             "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
             "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
             "requires": {
-                "es6-promisify": "^5.0.0"
+                "es6-promisify": "5.0.0"
             }
         },
         "ajv": {
@@ -1332,10 +1332,10 @@
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
             "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
             "requires": {
-                "fast-deep-equal": "^2.0.1",
-                "fast-json-stable-stringify": "^2.0.0",
-                "json-schema-traverse": "^0.4.1",
-                "uri-js": "^4.2.2"
+                "fast-deep-equal": "2.0.1",
+                "fast-json-stable-stringify": "2.0.0",
+                "json-schema-traverse": "0.4.1",
+                "uri-js": "4.2.2"
             }
         },
         "ajv-errors": {
@@ -1353,9 +1353,9 @@
             "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
             "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
             "requires": {
-                "kind-of": "^3.0.2",
-                "longest": "^1.0.1",
-                "repeat-string": "^1.5.2"
+                "kind-of": "3.2.2",
+                "longest": "1.0.1",
+                "repeat-string": "1.6.1"
             },
             "dependencies": {
                 "kind-of": {
@@ -1363,7 +1363,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -1383,7 +1383,7 @@
             "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
             "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
             "requires": {
-                "string-width": "^2.0.0"
+                "string-width": "2.1.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -1401,8 +1401,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -1410,7 +1410,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -1426,7 +1426,7 @@
             "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
             "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
             "requires": {
-                "array-back": "^3.0.1"
+                "array-back": "3.1.0"
             },
             "dependencies": {
                 "array-back": {
@@ -1462,8 +1462,8 @@
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
             "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
             "requires": {
-                "micromatch": "^3.1.4",
-                "normalize-path": "^2.1.1"
+                "micromatch": "3.1.10",
+                "normalize-path": "2.1.1"
             },
             "dependencies": {
                 "normalize-path": {
@@ -1471,7 +1471,7 @@
                     "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
                     "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
                     "requires": {
-                        "remove-trailing-separator": "^1.0.1"
+                        "remove-trailing-separator": "1.1.0"
                     }
                 }
             }
@@ -1486,13 +1486,13 @@
             "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.0.3.tgz",
             "integrity": "sha512-d0W7NUyXoLklozHHfvWnHoHS3dvQk8eB22pv5tBwcu1jEO5eZY8W+gHytkAaJ0R8fU2TnNThrWYxjvFlKvRxpw==",
             "requires": {
-                "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.0"
+                "archiver-utils": "2.1.0",
+                "async": "2.6.3",
+                "buffer-crc32": "0.2.13",
+                "glob": "7.1.4",
+                "readable-stream": "3.4.0",
+                "tar-stream": "2.1.0",
+                "zip-stream": "2.1.0"
             },
             "dependencies": {
                 "bl": {
@@ -1500,7 +1500,7 @@
                     "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
                     "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
                     "requires": {
-                        "readable-stream": "^3.0.1"
+                        "readable-stream": "3.4.0"
                     }
                 },
                 "readable-stream": {
@@ -1508,9 +1508,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "tar-stream": {
@@ -1518,11 +1518,11 @@
                     "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
                     "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
                     "requires": {
-                        "bl": "^3.0.0",
-                        "end-of-stream": "^1.4.1",
-                        "fs-constants": "^1.0.0",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^3.1.1"
+                        "bl": "3.0.0",
+                        "end-of-stream": "1.4.1",
+                        "fs-constants": "1.0.0",
+                        "inherits": "2.0.3",
+                        "readable-stream": "3.4.0"
                     }
                 }
             }
@@ -1532,16 +1532,16 @@
             "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
             "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
             "requires": {
-                "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"
+                "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.3.6"
             }
         },
         "are-we-there-yet": {
@@ -1549,8 +1549,8 @@
             "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
             "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
             "requires": {
-                "delegates": "^1.0.0",
-                "readable-stream": "^2.0.6"
+                "delegates": "1.0.0",
+                "readable-stream": "2.3.6"
             }
         },
         "argparse": {
@@ -1558,7 +1558,7 @@
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
             "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
             "requires": {
-                "sprintf-js": "~1.0.2"
+                "sprintf-js": "1.0.3"
             }
         },
         "arr-diff": {
@@ -1581,7 +1581,7 @@
             "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
             "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
             "requires": {
-                "typical": "^2.6.1"
+                "typical": "2.6.1"
             }
         },
         "array-batcher": {
@@ -1589,11 +1589,11 @@
             "resolved": "https://registry.npmjs.org/array-batcher/-/array-batcher-1.2.3.tgz",
             "integrity": "sha512-/IOrwn4ZJi7YqTZrs3k+wQN5nKhjtTqL5ZKkzB+sKJlPeJzpMnRc3o8T9yt8/ZJiSldd+PwTHjM+//UsaszOOw==",
             "requires": {
-                "@types/node": "^12.7.5",
-                "chai": "^4.2.0",
-                "mocha": "^6.2.0",
-                "request": "^2.88.0",
-                "request-promise": "^4.2.4"
+                "@types/node": "12.12.3",
+                "chai": "4.2.0",
+                "mocha": "6.2.2",
+                "request": "2.88.0",
+                "request-promise": "4.2.4"
             },
             "dependencies": {
                 "@types/node": {
@@ -1616,7 +1616,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "assert-plus": {
@@ -1644,9 +1644,9 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "debug": {
@@ -1654,7 +1654,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.1"
                     }
                 },
                 "find-up": {
@@ -1662,7 +1662,7 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "form-data": {
@@ -1670,9 +1670,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "get-caller-file": {
@@ -1685,12 +1685,12 @@
                     "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
                     "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "har-validator": {
@@ -1698,8 +1698,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "he": {
@@ -1712,9 +1712,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "is-fullwidth-code-point": {
@@ -1727,8 +1727,8 @@
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "mocha": {
@@ -1776,7 +1776,7 @@
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "qs": {
@@ -1789,26 +1789,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "oauth-sign": "0.9.0",
+                        "performance-now": "2.1.0",
+                        "qs": "6.5.2",
+                        "safe-buffer": "5.1.2",
+                        "tough-cookie": "2.4.3",
+                        "tunnel-agent": "0.6.0",
+                        "uuid": "3.3.2"
                     }
                 },
                 "require-main-filename": {
@@ -1821,9 +1821,9 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -1831,7 +1831,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "supports-color": {
@@ -1839,7 +1839,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
                     "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "which-module": {
@@ -1852,9 +1852,9 @@
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -1867,16 +1867,16 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
                     "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
                     "requires": {
-                        "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.1"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -1884,8 +1884,8 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -1912,7 +1912,7 @@
             "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
             "dev": true,
             "requires": {
-                "array-uniq": "^1.0.1"
+                "array-uniq": "1.0.3"
             }
         },
         "array-uniq": {
@@ -1947,7 +1947,7 @@
             "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
             "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
             "requires": {
-                "safer-buffer": "~2.1.0"
+                "safer-buffer": "2.1.2"
             }
         },
         "asn1.js": {
@@ -1955,9 +1955,9 @@
             "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
             "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
             "requires": {
-                "bn.js": "^4.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0"
+                "bn.js": "4.11.8",
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "assert": {
@@ -1966,7 +1966,7 @@
             "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
             "dev": true,
             "requires": {
-                "object-assign": "^4.1.1",
+                "object-assign": "4.1.1",
                 "util": "0.10.3"
             },
             "dependencies": {
@@ -2012,7 +2012,7 @@
             "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
             "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
             "requires": {
-                "lodash": "^4.17.14"
+                "lodash": "4.17.15"
             }
         },
         "async-each": {
@@ -2046,14 +2046,14 @@
             "integrity": "sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==",
             "dev": true,
             "requires": {
-                "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"
+                "chalk": "2.4.2",
+                "enhanced-resolve": "4.1.0",
+                "loader-utils": "1.2.3",
+                "lodash": "4.17.15",
+                "micromatch": "3.1.10",
+                "mkdirp": "0.5.1",
+                "source-map-support": "0.5.12",
+                "webpack-log": "1.2.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -2062,7 +2062,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -2071,9 +2071,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -2082,7 +2082,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -2103,9 +2103,9 @@
             "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
             "dev": true,
             "requires": {
-                "chalk": "^1.1.3",
-                "esutils": "^2.0.2",
-                "js-tokens": "^3.0.2"
+                "chalk": "1.1.3",
+                "esutils": "2.0.2",
+                "js-tokens": "3.0.2"
             },
             "dependencies": {
                 "js-tokens": {
@@ -2121,16 +2121,16 @@
             "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.23.tgz",
             "integrity": "sha512-1JiCyXU0t5S2xCbItejCduLGGcKmF3POT0Ujbexog2MI4IlRcIn/kWjkYwCUZlxpON0O5FC635yPl/3slr7cKQ==",
             "requires": {
-                "@babel/helper-module-imports": "^7.0.0",
+                "@babel/helper-module-imports": "7.7.4",
                 "@emotion/hash": "0.7.3",
                 "@emotion/memoize": "0.7.3",
-                "@emotion/serialize": "^0.11.14",
-                "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"
+                "@emotion/serialize": "0.11.14",
+                "babel-plugin-macros": "2.8.0",
+                "babel-plugin-syntax-jsx": "6.18.0",
+                "convert-source-map": "1.7.0",
+                "escape-string-regexp": "1.0.5",
+                "find-root": "1.1.0",
+                "source-map": "0.5.7"
             }
         },
         "babel-plugin-macros": {
@@ -2138,9 +2138,9 @@
             "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
             "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
             "requires": {
-                "@babel/runtime": "^7.7.2",
-                "cosmiconfig": "^6.0.0",
-                "resolve": "^1.12.0"
+                "@babel/runtime": "7.7.6",
+                "cosmiconfig": "6.0.0",
+                "resolve": "1.13.1"
             },
             "dependencies": {
                 "@babel/runtime": {
@@ -2148,7 +2148,7 @@
                     "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz",
                     "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==",
                     "requires": {
-                        "regenerator-runtime": "^0.13.2"
+                        "regenerator-runtime": "0.13.3"
                     }
                 },
                 "resolve": {
@@ -2156,7 +2156,7 @@
                     "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz",
                     "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==",
                     "requires": {
-                        "path-parse": "^1.0.6"
+                        "path-parse": "1.0.6"
                     }
                 }
             }
@@ -2171,8 +2171,8 @@
             "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
             "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
             "requires": {
-                "core-js": "^2.4.0",
-                "regenerator-runtime": "^0.11.0"
+                "core-js": "2.6.9",
+                "regenerator-runtime": "0.11.1"
             },
             "dependencies": {
                 "core-js": {
@@ -2192,10 +2192,10 @@
             "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
             "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
             "requires": {
-                "babel-runtime": "^6.26.0",
-                "esutils": "^2.0.2",
-                "lodash": "^4.17.4",
-                "to-fast-properties": "^1.0.3"
+                "babel-runtime": "6.26.0",
+                "esutils": "2.0.2",
+                "lodash": "4.17.15",
+                "to-fast-properties": "1.0.3"
             },
             "dependencies": {
                 "to-fast-properties": {
@@ -2225,13 +2225,13 @@
             "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
             "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
             "requires": {
-                "cache-base": "^1.0.1",
-                "class-utils": "^0.3.5",
-                "component-emitter": "^1.2.1",
-                "define-property": "^1.0.0",
-                "isobject": "^3.0.1",
-                "mixin-deep": "^1.2.0",
-                "pascalcase": "^0.1.1"
+                "cache-base": "1.0.1",
+                "class-utils": "0.3.6",
+                "component-emitter": "1.3.0",
+                "define-property": "1.0.0",
+                "isobject": "3.0.1",
+                "mixin-deep": "1.3.2",
+                "pascalcase": "0.1.1"
             },
             "dependencies": {
                 "define-property": {
@@ -2239,7 +2239,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -2247,7 +2247,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -2255,7 +2255,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -2263,9 +2263,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -2311,7 +2311,7 @@
             "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
             "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
             "requires": {
-                "tweetnacl": "^0.14.3"
+                "tweetnacl": "0.14.5"
             }
         },
         "better-assert": {
@@ -2342,8 +2342,8 @@
             "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
             "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
             "requires": {
-                "readable-stream": "^2.3.5",
-                "safe-buffer": "^5.1.1"
+                "readable-stream": "2.3.6",
+                "safe-buffer": "5.1.2"
             }
         },
         "blob": {
@@ -2356,7 +2356,7 @@
             "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
             "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
             "requires": {
-                "inherits": "~2.0.0"
+                "inherits": "2.0.3"
             }
         },
         "bluebird": {
@@ -2380,15 +2380,15 @@
             "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
             "requires": {
                 "bytes": "3.1.0",
-                "content-type": "~1.0.4",
+                "content-type": "1.0.4",
                 "debug": "2.6.9",
-                "depd": "~1.1.2",
+                "depd": "1.1.2",
                 "http-errors": "1.7.2",
                 "iconv-lite": "0.4.24",
-                "on-finished": "~2.3.0",
+                "on-finished": "2.3.0",
                 "qs": "6.7.0",
                 "raw-body": "2.4.0",
-                "type-is": "~1.6.17"
+                "type-is": "1.6.18"
             }
         },
         "bonjour": {
@@ -2397,12 +2397,12 @@
             "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
             "dev": true,
             "requires": {
-                "array-flatten": "^2.1.0",
-                "deep-equal": "^1.0.1",
-                "dns-equal": "^1.0.0",
-                "dns-txt": "^2.0.2",
-                "multicast-dns": "^6.0.1",
-                "multicast-dns-service-types": "^1.1.0"
+                "array-flatten": "2.1.2",
+                "deep-equal": "1.0.1",
+                "dns-equal": "1.0.0",
+                "dns-txt": "2.0.2",
+                "multicast-dns": "6.2.3",
+                "multicast-dns-service-types": "1.1.0"
             },
             "dependencies": {
                 "array-flatten": {
@@ -2423,7 +2423,7 @@
             "resolved": "https://registry.npmjs.org/boolify-string/-/boolify-string-2.0.2.tgz",
             "integrity": "sha1-n4m9l9YKFEijlAF8SjuaPSQNRY4=",
             "requires": {
-                "type-detect": "^1.0.0"
+                "type-detect": "1.0.0"
             },
             "dependencies": {
                 "type-detect": {
@@ -2443,13 +2443,13 @@
             "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
             "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
             "requires": {
-                "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"
+                "ansi-align": "2.0.0",
+                "camelcase": "4.1.0",
+                "chalk": "2.4.2",
+                "cli-boxes": "1.0.0",
+                "string-width": "2.1.1",
+                "term-size": "1.2.0",
+                "widest-line": "2.0.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -2462,7 +2462,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -2470,9 +2470,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "is-fullwidth-code-point": {
@@ -2485,8 +2485,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -2494,7 +2494,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 },
                 "supports-color": {
@@ -2502,7 +2502,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -2512,7 +2512,7 @@
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "requires": {
-                "balanced-match": "^1.0.0",
+                "balanced-match": "1.0.0",
                 "concat-map": "0.0.1"
             }
         },
@@ -2521,16 +2521,16 @@
             "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
             "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
             "requires": {
-                "arr-flatten": "^1.1.0",
-                "array-unique": "^0.3.2",
-                "extend-shallow": "^2.0.1",
-                "fill-range": "^4.0.0",
-                "isobject": "^3.0.1",
-                "repeat-element": "^1.1.2",
-                "snapdragon": "^0.8.1",
-                "snapdragon-node": "^2.0.1",
-                "split-string": "^3.0.2",
-                "to-regex": "^3.0.1"
+                "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.3",
+                "snapdragon": "0.8.2",
+                "snapdragon-node": "2.1.1",
+                "split-string": "3.1.0",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -2538,7 +2538,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -2564,12 +2564,12 @@
             "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
             "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
             "requires": {
-                "buffer-xor": "^1.0.3",
-                "cipher-base": "^1.0.0",
-                "create-hash": "^1.1.0",
-                "evp_bytestokey": "^1.0.3",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "buffer-xor": "1.0.3",
+                "cipher-base": "1.0.4",
+                "create-hash": "1.2.0",
+                "evp_bytestokey": "1.0.3",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "browserify-cipher": {
@@ -2577,9 +2577,9 @@
             "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
             "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
             "requires": {
-                "browserify-aes": "^1.0.4",
-                "browserify-des": "^1.0.0",
-                "evp_bytestokey": "^1.0.0"
+                "browserify-aes": "1.2.0",
+                "browserify-des": "1.0.2",
+                "evp_bytestokey": "1.0.3"
             }
         },
         "browserify-des": {
@@ -2587,10 +2587,10 @@
             "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
             "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
             "requires": {
-                "cipher-base": "^1.0.1",
-                "des.js": "^1.0.0",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "cipher-base": "1.0.4",
+                "des.js": "1.0.0",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "browserify-rsa": {
@@ -2598,8 +2598,8 @@
             "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
             "requires": {
-                "bn.js": "^4.1.0",
-                "randombytes": "^2.0.1"
+                "bn.js": "4.11.8",
+                "randombytes": "2.1.0"
             }
         },
         "browserify-sign": {
@@ -2607,13 +2607,13 @@
             "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
             "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
             "requires": {
-                "bn.js": "^4.1.1",
-                "browserify-rsa": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "create-hmac": "^1.1.2",
-                "elliptic": "^6.0.0",
-                "inherits": "^2.0.1",
-                "parse-asn1": "^5.0.0"
+                "bn.js": "4.11.8",
+                "browserify-rsa": "4.0.1",
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "elliptic": "6.5.0",
+                "inherits": "2.0.3",
+                "parse-asn1": "5.1.4"
             }
         },
         "browserify-zlib": {
@@ -2622,7 +2622,7 @@
             "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
             "dev": true,
             "requires": {
-                "pako": "~1.0.5"
+                "pako": "1.0.10"
             }
         },
         "bson": {
@@ -2636,9 +2636,9 @@
             "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
             "dev": true,
             "requires": {
-                "base64-js": "^1.0.2",
-                "ieee754": "^1.1.4",
-                "isarray": "^1.0.0"
+                "base64-js": "1.3.0",
+                "ieee754": "1.1.13",
+                "isarray": "1.0.0"
             }
         },
         "buffer-alloc": {
@@ -2646,8 +2646,8 @@
             "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
             "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
             "requires": {
-                "buffer-alloc-unsafe": "^1.1.0",
-                "buffer-fill": "^1.0.0"
+                "buffer-alloc-unsafe": "1.1.0",
+                "buffer-fill": "1.0.0"
             }
         },
         "buffer-alloc-unsafe": {
@@ -2714,19 +2714,19 @@
             "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
             "dev": true,
             "requires": {
-                "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"
+                "bluebird": "3.5.5",
+                "chownr": "1.1.2",
+                "glob": "7.1.4",
+                "graceful-fs": "4.2.0",
+                "lru-cache": "4.1.5",
+                "mississippi": "2.0.0",
+                "mkdirp": "0.5.1",
+                "move-concurrently": "1.0.1",
+                "promise-inflight": "1.0.1",
+                "rimraf": "2.7.1",
+                "ssri": "5.3.0",
+                "unique-filename": "1.1.1",
+                "y18n": "4.0.0"
             },
             "dependencies": {
                 "rimraf": {
@@ -2735,7 +2735,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "y18n": {
@@ -2751,15 +2751,15 @@
             "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
             "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
             "requires": {
-                "collection-visit": "^1.0.0",
-                "component-emitter": "^1.2.1",
-                "get-value": "^2.0.6",
-                "has-value": "^1.0.0",
-                "isobject": "^3.0.1",
-                "set-value": "^2.0.0",
-                "to-object-path": "^0.3.0",
-                "union-value": "^1.0.0",
-                "unset-value": "^1.0.0"
+                "collection-visit": "1.0.0",
+                "component-emitter": "1.3.0",
+                "get-value": "2.0.6",
+                "has-value": "1.0.0",
+                "isobject": "3.0.1",
+                "set-value": "2.0.1",
+                "to-object-path": "0.3.0",
+                "union-value": "1.0.1",
+                "unset-value": "1.0.0"
             }
         },
         "callsite": {
@@ -2782,8 +2782,8 @@
             "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
             "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
             "requires": {
-                "camelcase": "^2.0.0",
-                "map-obj": "^1.0.0"
+                "camelcase": "2.1.1",
+                "map-obj": "1.0.1"
             },
             "dependencies": {
                 "camelcase": {
@@ -2798,9 +2798,9 @@
             "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.5.0.tgz",
             "integrity": "sha512-wwRz2cLMgb9d+rnotOJCoc04Bzj3aJMpWc6JxAD6lP7bYz0ldcn0sKddoZ0vhD5T8HBxrK+XmRDJb68/2VqARw==",
             "requires": {
-                "nan": "^2.13.2",
-                "node-pre-gyp": "^0.11.0",
-                "simple-get": "^3.0.3"
+                "nan": "2.14.0",
+                "node-pre-gyp": "0.11.0",
+                "simple-get": "3.0.3"
             }
         },
         "capture-stack-trace": {
@@ -2818,8 +2818,8 @@
             "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
             "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
             "requires": {
-                "align-text": "^0.1.3",
-                "lazy-cache": "^1.0.3"
+                "align-text": "0.1.4",
+                "lazy-cache": "1.0.4"
             }
         },
         "chai": {
@@ -2827,12 +2827,12 @@
             "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
             "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
             "requires": {
-                "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"
+                "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.8"
             }
         },
         "chained-function": {
@@ -2845,11 +2845,11 @@
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
             "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
             "requires": {
-                "ansi-styles": "^2.2.1",
-                "escape-string-regexp": "^1.0.2",
-                "has-ansi": "^2.0.0",
-                "strip-ansi": "^3.0.0",
-                "supports-color": "^2.0.0"
+                "ansi-styles": "2.2.1",
+                "escape-string-regexp": "1.0.5",
+                "has-ansi": "2.0.0",
+                "strip-ansi": "3.0.1",
+                "supports-color": "2.0.0"
             }
         },
         "character-parser": {
@@ -2857,7 +2857,7 @@
             "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
             "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
             "requires": {
-                "is-regex": "^1.0.3"
+                "is-regex": "1.0.4"
             }
         },
         "check-error": {
@@ -2870,12 +2870,12 @@
             "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
             "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
             "requires": {
-                "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"
+                "css-select": "1.2.0",
+                "dom-serializer": "0.1.1",
+                "entities": "1.1.2",
+                "htmlparser2": "3.10.1",
+                "lodash": "4.17.15",
+                "parse5": "3.0.3"
             },
             "dependencies": {
                 "parse5": {
@@ -2883,7 +2883,7 @@
                     "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
                     "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
                     "requires": {
-                        "@types/node": "*"
+                        "@types/node": "10.14.13"
                     }
                 }
             }
@@ -2898,18 +2898,18 @@
             "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
             "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
             "requires": {
-                "anymatch": "^2.0.0",
-                "async-each": "^1.0.1",
-                "braces": "^2.3.2",
-                "fsevents": "^1.2.7",
-                "glob-parent": "^3.1.0",
-                "inherits": "^2.0.3",
-                "is-binary-path": "^1.0.0",
-                "is-glob": "^4.0.0",
-                "normalize-path": "^3.0.0",
-                "path-is-absolute": "^1.0.0",
-                "readdirp": "^2.2.1",
-                "upath": "^1.1.1"
+                "anymatch": "2.0.0",
+                "async-each": "1.0.3",
+                "braces": "2.3.2",
+                "fsevents": "1.2.9",
+                "glob-parent": "3.1.0",
+                "inherits": "2.0.3",
+                "is-binary-path": "1.0.1",
+                "is-glob": "4.0.1",
+                "normalize-path": "3.0.0",
+                "path-is-absolute": "1.0.1",
+                "readdirp": "2.2.1",
+                "upath": "1.1.2"
             }
         },
         "chownr": {
@@ -2923,7 +2923,7 @@
             "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
             "dev": true,
             "requires": {
-                "tslib": "^1.9.0"
+                "tslib": "1.10.0"
             }
         },
         "ci-info": {
@@ -2936,8 +2936,8 @@
             "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
             "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "class-transformer": {
@@ -2950,10 +2950,10 @@
             "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
             "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
             "requires": {
-                "arr-union": "^3.1.0",
-                "define-property": "^0.2.5",
-                "isobject": "^3.0.0",
-                "static-extend": "^0.1.1"
+                "arr-union": "3.1.0",
+                "define-property": "0.2.5",
+                "isobject": "3.0.1",
+                "static-extend": "0.1.2"
             },
             "dependencies": {
                 "define-property": {
@@ -2961,7 +2961,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 }
             }
@@ -2976,7 +2976,7 @@
             "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
             "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
             "requires": {
-                "source-map": "~0.6.0"
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -2996,14 +2996,14 @@
             "resolved": "https://registry.npmjs.org/cliss/-/cliss-0.0.2.tgz",
             "integrity": "sha512-6rj9pgdukjT994Md13JCUAgTk91abAKrygL9sAvmHY4F6AKMOV8ccGaxhUUfcBuyg3sundWnn3JE0Mc9W6ZYqw==",
             "requires": {
-                "command-line-usage": "^4.0.1",
-                "deepmerge": "^2.0.0",
-                "get-stdin": "^5.0.1",
+                "command-line-usage": "4.1.0",
+                "deepmerge": "2.2.1",
+                "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"
+                "pipe-functions": "1.3.0",
+                "strip-ansi": "4.0.0",
+                "yargs-parser": "7.0.0"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -3016,7 +3016,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -3026,9 +3026,9 @@
             "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
             "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
             "requires": {
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1",
-                "wrap-ansi": "^2.0.0"
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wrap-ansi": "2.1.0"
             }
         },
         "clj-fuzzy": {
@@ -3042,10 +3042,10 @@
             "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
             "dev": true,
             "requires": {
-                "for-own": "^1.0.0",
-                "is-plain-object": "^2.0.4",
-                "kind-of": "^6.0.0",
-                "shallow-clone": "^1.0.0"
+                "for-own": "1.0.0",
+                "is-plain-object": "2.0.4",
+                "kind-of": "6.0.2",
+                "shallow-clone": "1.0.0"
             }
         },
         "code-point-at": {
@@ -3058,8 +3058,8 @@
             "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
             "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
             "requires": {
-                "map-visit": "^1.0.0",
-                "object-visit": "^1.0.0"
+                "map-visit": "1.0.0",
+                "object-visit": "1.0.1"
             }
         },
         "color": {
@@ -3067,8 +3067,8 @@
             "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
             "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
             "requires": {
-                "color-convert": "^1.9.1",
-                "color-string": "^1.5.2"
+                "color-convert": "1.9.3",
+                "color-string": "1.5.3"
             }
         },
         "color-convert": {
@@ -3089,8 +3089,8 @@
             "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
             "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
             "requires": {
-                "color-name": "^1.0.0",
-                "simple-swizzle": "^0.2.2"
+                "color-name": "1.1.3",
+                "simple-swizzle": "0.2.2"
             }
         },
         "colors": {
@@ -3103,7 +3103,7 @@
             "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
             "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
             "requires": {
-                "delayed-stream": "~1.0.0"
+                "delayed-stream": "1.0.0"
             }
         },
         "command-line-usage": {
@@ -3111,10 +3111,10 @@
             "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
             "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
             "requires": {
-                "ansi-escape-sequences": "^4.0.0",
-                "array-back": "^2.0.0",
-                "table-layout": "^0.4.2",
-                "typical": "^2.6.1"
+                "ansi-escape-sequences": "4.1.0",
+                "array-back": "2.0.0",
+                "table-layout": "0.4.5",
+                "typical": "2.6.1"
             }
         },
         "commander": {
@@ -3133,15 +3133,15 @@
             "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz",
             "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=",
             "requires": {
-                "commander": "^2.5.0",
-                "detective": "^4.3.1",
-                "glob": "^5.0.15",
-                "graceful-fs": "^4.1.2",
-                "iconv-lite": "^0.4.5",
-                "mkdirp": "^0.5.0",
-                "private": "^0.1.6",
-                "q": "^1.1.2",
-                "recast": "^0.11.17"
+                "commander": "2.20.0",
+                "detective": "4.7.1",
+                "glob": "5.0.15",
+                "graceful-fs": "4.2.0",
+                "iconv-lite": "0.4.24",
+                "mkdirp": "0.5.1",
+                "private": "0.1.8",
+                "q": "1.5.1",
+                "recast": "0.11.23"
             },
             "dependencies": {
                 "glob": {
@@ -3149,11 +3149,11 @@
                     "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
                     "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
                     "requires": {
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "2 || 3",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 }
             }
@@ -3178,10 +3178,10 @@
             "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.0.0.tgz",
             "integrity": "sha512-gnETNngrfsAoLBENM8M0DoiCDJkHwz3OfIg4mBtqKDcRgE4oXNwHxHxgHvwKKlrcD7eZ7BVTy4l8t9xVF7q3FQ==",
             "requires": {
-                "buffer-crc32": "^0.2.13",
-                "crc32-stream": "^2.0.0",
-                "normalize-path": "^3.0.0",
-                "readable-stream": "^2.3.6"
+                "buffer-crc32": "0.2.13",
+                "crc32-stream": "2.0.0",
+                "normalize-path": "3.0.0",
+                "readable-stream": "2.3.6"
             }
         },
         "compressible": {
@@ -3190,7 +3190,7 @@
             "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
             "dev": true,
             "requires": {
-                "mime-db": ">= 1.40.0 < 2"
+                "mime-db": "1.40.0"
             }
         },
         "compression": {
@@ -3199,13 +3199,13 @@
             "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
             "dev": true,
             "requires": {
-                "accepts": "~1.3.5",
+                "accepts": "1.3.7",
                 "bytes": "3.0.0",
-                "compressible": "~2.0.16",
+                "compressible": "2.0.17",
                 "debug": "2.6.9",
-                "on-headers": "~1.0.2",
+                "on-headers": "1.0.2",
                 "safe-buffer": "5.1.2",
-                "vary": "~1.1.2"
+                "vary": "1.1.2"
             },
             "dependencies": {
                 "bytes": {
@@ -3227,10 +3227,10 @@
             "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
             "dev": true,
             "requires": {
-                "buffer-from": "^1.0.0",
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.2.2",
-                "typedarray": "^0.0.6"
+                "buffer-from": "1.1.1",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "typedarray": "0.0.6"
             }
         },
         "configstore": {
@@ -3238,12 +3238,12 @@
             "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
             "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
             "requires": {
-                "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"
+                "dot-prop": "4.2.0",
+                "graceful-fs": "4.2.0",
+                "make-dir": "1.3.0",
+                "unique-string": "1.0.0",
+                "write-file-atomic": "2.4.3",
+                "xdg-basedir": "3.0.0"
             }
         },
         "connect-flash": {
@@ -3262,7 +3262,7 @@
             "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.3.tgz",
             "integrity": "sha512-Vs+QZ/6X6gbCrP1Ls7Oh/wlyY6pgpbPSrUKF5yRT+zd+4GZPNbjNquxquZ+Clv2+03HBXE7T4lVM0PUcaBhihg==",
             "requires": {
-                "mongodb": "^2.0.36"
+                "mongodb": "2.2.36"
             },
             "dependencies": {
                 "mongodb": {
@@ -3285,13 +3285,13 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
                     "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
                     "requires": {
-                        "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"
+                        "buffer-shims": "1.0.0",
+                        "core-util-is": "1.0.2",
+                        "inherits": "2.0.3",
+                        "isarray": "1.0.0",
+                        "process-nextick-args": "1.0.7",
+                        "string_decoder": "1.0.3",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "string_decoder": {
@@ -3299,7 +3299,7 @@
                     "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
                     "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 }
             }
@@ -3310,7 +3310,7 @@
             "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
             "dev": true,
             "requires": {
-                "date-now": "^0.1.4"
+                "date-now": "0.1.4"
             }
         },
         "console-control-strings": {
@@ -3323,10 +3323,10 @@
             "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
             "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
             "requires": {
-                "@types/babel-types": "^7.0.0",
-                "@types/babylon": "^6.16.2",
-                "babel-types": "^6.26.0",
-                "babylon": "^6.18.0"
+                "@types/babel-types": "7.0.7",
+                "@types/babylon": "6.16.5",
+                "babel-types": "6.26.0",
+                "babylon": "6.18.0"
             }
         },
         "constants-browserify": {
@@ -3353,7 +3353,7 @@
             "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
             "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
             "requires": {
-                "safe-buffer": "~5.1.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "cookie": {
@@ -3377,7 +3377,7 @@
             "requires": {
                 "cookies": "0.7.1",
                 "debug": "3.1.0",
-                "on-headers": "~1.0.1",
+                "on-headers": "1.0.2",
                 "safe-buffer": "5.1.1"
             },
             "dependencies": {
@@ -3406,8 +3406,8 @@
             "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
             "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=",
             "requires": {
-                "depd": "~1.1.1",
-                "keygrip": "~1.0.2"
+                "depd": "1.1.2",
+                "keygrip": "1.0.3"
             }
         },
         "copy-concurrently": {
@@ -3416,12 +3416,12 @@
             "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1",
-                "fs-write-stream-atomic": "^1.0.8",
-                "iferr": "^0.1.5",
-                "mkdirp": "^0.5.1",
-                "rimraf": "^2.5.4",
-                "run-queue": "^1.0.0"
+                "aproba": "1.2.0",
+                "fs-write-stream-atomic": "1.0.10",
+                "iferr": "0.1.5",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1",
+                "run-queue": "1.0.3"
             },
             "dependencies": {
                 "rimraf": {
@@ -3430,7 +3430,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -3446,14 +3446,14 @@
             "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==",
             "dev": true,
             "requires": {
-                "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"
+                "cacache": "10.0.4",
+                "find-cache-dir": "1.0.0",
+                "globby": "7.1.1",
+                "is-glob": "4.0.1",
+                "loader-utils": "1.2.3",
+                "minimatch": "3.0.4",
+                "p-limit": "1.3.0",
+                "serialize-javascript": "1.7.0"
             },
             "dependencies": {
                 "p-limit": {
@@ -3462,7 +3462,7 @@
                     "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
                     "dev": true,
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 }
             }
@@ -3482,8 +3482,8 @@
             "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
             "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
             "requires": {
-                "object-assign": "^4",
-                "vary": "^1"
+                "object-assign": "4.1.1",
+                "vary": "1.1.2"
             }
         },
         "cosmiconfig": {
@@ -3491,11 +3491,11 @@
             "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
             "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
             "requires": {
-                "@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"
+                "@types/parse-json": "4.0.0",
+                "import-fresh": "3.2.1",
+                "parse-json": "5.0.0",
+                "path-type": "4.0.0",
+                "yaml": "1.7.2"
             },
             "dependencies": {
                 "path-type": {
@@ -3510,7 +3510,7 @@
             "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
             "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
             "requires": {
-                "buffer": "^5.1.0"
+                "buffer": "5.2.1"
             },
             "dependencies": {
                 "buffer": {
@@ -3518,8 +3518,8 @@
                     "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
                     "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
                     "requires": {
-                        "base64-js": "^1.0.2",
-                        "ieee754": "^1.1.4"
+                        "base64-js": "1.3.0",
+                        "ieee754": "1.1.13"
                     }
                 }
             }
@@ -3529,8 +3529,8 @@
             "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
             "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
             "requires": {
-                "crc": "^3.4.4",
-                "readable-stream": "^2.0.0"
+                "crc": "3.8.0",
+                "readable-stream": "2.3.6"
             }
         },
         "create-ecdh": {
@@ -3538,8 +3538,8 @@
             "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
             "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "elliptic": "^6.0.0"
+                "bn.js": "4.11.8",
+                "elliptic": "6.5.0"
             }
         },
         "create-emotion": {
@@ -3547,8 +3547,8 @@
             "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.14.tgz",
             "integrity": "sha512-5G4naKMxokOur+94eDz7iPKBfwzy4wa/+0isnPhxXyosIQHBq7yvBy4jjdZw/nnRm7G3PM7P9Ug8mUmtoqcaHg==",
             "requires": {
-                "@emotion/cache": "^10.0.14",
-                "@emotion/serialize": "^0.11.8",
+                "@emotion/cache": "10.0.19",
+                "@emotion/serialize": "0.11.14",
                 "@emotion/sheet": "0.9.3",
                 "@emotion/utils": "0.11.2"
             }
@@ -3558,7 +3558,7 @@
             "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
             "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
             "requires": {
-                "capture-stack-trace": "^1.0.0"
+                "capture-stack-trace": "1.0.1"
             }
         },
         "create-hash": {
@@ -3566,11 +3566,11 @@
             "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
             "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
             "requires": {
-                "cipher-base": "^1.0.1",
-                "inherits": "^2.0.1",
-                "md5.js": "^1.3.4",
-                "ripemd160": "^2.0.1",
-                "sha.js": "^2.4.0"
+                "cipher-base": "1.0.4",
+                "inherits": "2.0.3",
+                "md5.js": "1.3.5",
+                "ripemd160": "2.0.2",
+                "sha.js": "2.4.11"
             }
         },
         "create-hmac": {
@@ -3578,12 +3578,12 @@
             "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
             "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
             "requires": {
-                "cipher-base": "^1.0.3",
-                "create-hash": "^1.1.0",
-                "inherits": "^2.0.1",
-                "ripemd160": "^2.0.0",
-                "safe-buffer": "^5.0.1",
-                "sha.js": "^2.4.8"
+                "cipher-base": "1.0.4",
+                "create-hash": "1.2.0",
+                "inherits": "2.0.3",
+                "ripemd160": "2.0.2",
+                "safe-buffer": "5.1.2",
+                "sha.js": "2.4.11"
             }
         },
         "create-react-context": {
@@ -3591,8 +3591,8 @@
             "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
             "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
             "requires": {
-                "fbjs": "^0.8.0",
-                "gud": "^1.0.0"
+                "fbjs": "0.8.17",
+                "gud": "1.0.0"
             }
         },
         "crel": {
@@ -3606,8 +3606,8 @@
             "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==",
             "dev": true,
             "requires": {
-                "cross-spawn": "^6.0.5",
-                "is-windows": "^1.0.0"
+                "cross-spawn": "6.0.5",
+                "is-windows": "1.0.2"
             },
             "dependencies": {
                 "cross-spawn": {
@@ -3616,11 +3616,11 @@
                     "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
                     "dev": true,
                     "requires": {
-                        "nice-try": "^1.0.4",
-                        "path-key": "^2.0.1",
-                        "semver": "^5.5.0",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "nice-try": "1.0.5",
+                        "path-key": "2.0.1",
+                        "semver": "5.7.0",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     }
                 }
             }
@@ -3646,8 +3646,8 @@
             "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
             "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
             "requires": {
-                "lru-cache": "^4.0.1",
-                "which": "^1.2.9"
+                "lru-cache": "4.1.5",
+                "which": "1.3.1"
             }
         },
         "crypto-browserify": {
@@ -3655,17 +3655,17 @@
             "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
             "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
             "requires": {
-                "browserify-cipher": "^1.0.0",
-                "browserify-sign": "^4.0.0",
-                "create-ecdh": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "create-hmac": "^1.1.0",
-                "diffie-hellman": "^5.0.0",
-                "inherits": "^2.0.1",
-                "pbkdf2": "^3.0.3",
-                "public-encrypt": "^4.0.0",
-                "randombytes": "^2.0.0",
-                "randomfill": "^1.0.3"
+                "browserify-cipher": "1.0.1",
+                "browserify-sign": "4.0.4",
+                "create-ecdh": "4.0.3",
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "diffie-hellman": "5.0.3",
+                "inherits": "2.0.3",
+                "pbkdf2": "3.0.17",
+                "public-encrypt": "4.0.3",
+                "randombytes": "2.1.0",
+                "randomfill": "1.0.4"
             }
         },
         "crypto-random-string": {
@@ -3679,17 +3679,17 @@
             "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==",
             "dev": true,
             "requires": {
-                "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"
+                "camelcase": "5.3.1",
+                "icss-utils": "4.1.1",
+                "loader-utils": "1.2.3",
+                "normalize-path": "3.0.0",
+                "postcss": "7.0.17",
+                "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.1",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -3704,9 +3704,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -3716,10 +3716,10 @@
             "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
             "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
             "requires": {
-                "boolbase": "~1.0.0",
-                "css-what": "2.1",
+                "boolbase": "1.0.0",
+                "css-what": "2.1.3",
                 "domutils": "1.5.1",
-                "nth-check": "~1.0.1"
+                "nth-check": "1.0.2"
             }
         },
         "css-what": {
@@ -3745,7 +3745,7 @@
             "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
             "dev": true,
             "requires": {
-                "cssom": "0.3.x"
+                "cssom": "0.3.8"
             }
         },
         "csstype": {
@@ -3758,7 +3758,7 @@
             "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
             "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
             "requires": {
-                "array-find-index": "^1.0.1"
+                "array-find-index": "1.0.2"
             }
         },
         "cyclist": {
@@ -3773,8 +3773,8 @@
             "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
             "dev": true,
             "requires": {
-                "es5-ext": "^0.10.50",
-                "type": "^1.0.1"
+                "es5-ext": "0.10.50",
+                "type": "1.0.1"
             }
         },
         "d3-format": {
@@ -3787,7 +3787,7 @@
             "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
             "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
             "requires": {
-                "assert-plus": "^1.0.0"
+                "assert-plus": "1.0.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -3803,9 +3803,9 @@
             "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
             "dev": true,
             "requires": {
-                "abab": "^2.0.0",
-                "whatwg-mimetype": "^2.2.0",
-                "whatwg-url": "^7.0.0"
+                "abab": "2.0.0",
+                "whatwg-mimetype": "2.3.0",
+                "whatwg-url": "7.0.0"
             }
         },
         "date-now": {
@@ -3820,8 +3820,8 @@
             "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
             "dev": true,
             "requires": {
-                "get-stdin": "^4.0.1",
-                "meow": "^3.3.0"
+                "get-stdin": "4.0.1",
+                "meow": "3.7.0"
             },
             "dependencies": {
                 "get-stdin": {
@@ -3861,7 +3861,7 @@
             "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
             "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
             "requires": {
-                "mimic-response": "^1.0.0"
+                "mimic-response": "1.0.1"
             }
         },
         "deep-eql": {
@@ -3869,7 +3869,7 @@
             "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
             "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
             "requires": {
-                "type-detect": "^4.0.0"
+                "type-detect": "4.0.8"
             }
         },
         "deep-equal": {
@@ -3900,8 +3900,8 @@
             "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
             "dev": true,
             "requires": {
-                "execa": "^1.0.0",
-                "ip-regex": "^2.1.0"
+                "execa": "1.0.0",
+                "ip-regex": "2.1.0"
             },
             "dependencies": {
                 "cross-spawn": {
@@ -3910,11 +3910,11 @@
                     "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
                     "dev": true,
                     "requires": {
-                        "nice-try": "^1.0.4",
-                        "path-key": "^2.0.1",
-                        "semver": "^5.5.0",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "nice-try": "1.0.5",
+                        "path-key": "2.0.1",
+                        "semver": "5.7.0",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     }
                 },
                 "execa": {
@@ -3923,13 +3923,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "get-stream": {
@@ -3938,7 +3938,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "pump": {
@@ -3947,8 +3947,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 }
             }
@@ -3958,7 +3958,7 @@
             "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
             "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
             "requires": {
-                "object-keys": "^1.0.12"
+                "object-keys": "1.1.1"
             }
         },
         "define-property": {
@@ -3966,8 +3966,8 @@
             "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
             "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
             "requires": {
-                "is-descriptor": "^1.0.2",
-                "isobject": "^3.0.1"
+                "is-descriptor": "1.0.2",
+                "isobject": "3.0.1"
             },
             "dependencies": {
                 "is-accessor-descriptor": {
@@ -3975,7 +3975,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -3983,7 +3983,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -3991,9 +3991,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -4009,13 +4009,13 @@
             "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
             "dev": true,
             "requires": {
-                "@types/glob": "^7.1.1",
-                "globby": "^6.1.0",
-                "is-path-cwd": "^2.0.0",
-                "is-path-in-cwd": "^2.0.0",
-                "p-map": "^2.0.0",
-                "pify": "^4.0.1",
-                "rimraf": "^2.6.3"
+                "@types/glob": "7.1.1",
+                "globby": "6.1.0",
+                "is-path-cwd": "2.2.0",
+                "is-path-in-cwd": "2.1.0",
+                "p-map": "2.1.0",
+                "pify": "4.0.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "globby": {
@@ -4024,11 +4024,11 @@
                     "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
                     "dev": true,
                     "requires": {
-                        "array-union": "^1.0.1",
-                        "glob": "^7.0.3",
-                        "object-assign": "^4.0.1",
-                        "pify": "^2.0.0",
-                        "pinkie-promise": "^2.0.0"
+                        "array-union": "1.0.2",
+                        "glob": "7.1.4",
+                        "object-assign": "4.1.1",
+                        "pify": "2.3.0",
+                        "pinkie-promise": "2.0.1"
                     },
                     "dependencies": {
                         "pify": {
@@ -4051,7 +4051,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -4076,8 +4076,8 @@
             "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
             "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
             "requires": {
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0"
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "destroy": {
@@ -4107,8 +4107,8 @@
             "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz",
             "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==",
             "requires": {
-                "acorn": "^5.2.1",
-                "defined": "^1.0.0"
+                "acorn": "5.7.3",
+                "defined": "1.0.0"
             }
         },
         "diff": {
@@ -4121,9 +4121,9 @@
             "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
             "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "miller-rabin": "^4.0.0",
-                "randombytes": "^2.0.0"
+                "bn.js": "4.11.8",
+                "miller-rabin": "4.0.1",
+                "randombytes": "2.1.0"
             }
         },
         "dir-glob": {
@@ -4132,7 +4132,7 @@
             "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
             "dev": true,
             "requires": {
-                "path-type": "^3.0.0"
+                "path-type": "3.0.0"
             },
             "dependencies": {
                 "path-type": {
@@ -4141,7 +4141,7 @@
                     "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
                     "dev": true,
                     "requires": {
-                        "pify": "^3.0.0"
+                        "pify": "3.0.0"
                     }
                 },
                 "pify": {
@@ -4164,8 +4164,8 @@
             "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
             "dev": true,
             "requires": {
-                "ip": "^1.1.0",
-                "safe-buffer": "^5.0.1"
+                "ip": "1.1.5",
+                "safe-buffer": "5.1.2"
             }
         },
         "dns-txt": {
@@ -4174,7 +4174,7 @@
             "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
             "dev": true,
             "requires": {
-                "buffer-indexof": "^1.0.0"
+                "buffer-indexof": "1.1.1"
             }
         },
         "doctypes": {
@@ -4187,7 +4187,7 @@
             "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
             "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
             "requires": {
-                "@babel/runtime": "^7.1.2"
+                "@babel/runtime": "7.5.5"
             }
         },
         "dom-serializer": {
@@ -4195,8 +4195,8 @@
             "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
             "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
             "requires": {
-                "domelementtype": "^1.3.0",
-                "entities": "^1.1.1"
+                "domelementtype": "1.3.1",
+                "entities": "1.1.2"
             }
         },
         "domain-browser": {
@@ -4216,7 +4216,7 @@
             "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
             "dev": true,
             "requires": {
-                "webidl-conversions": "^4.0.2"
+                "webidl-conversions": "4.0.2"
             }
         },
         "domhandler": {
@@ -4224,7 +4224,7 @@
             "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
             "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
             "requires": {
-                "domelementtype": "1"
+                "domelementtype": "1.3.1"
             }
         },
         "domutils": {
@@ -4232,8 +4232,8 @@
             "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
             "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
             "requires": {
-                "dom-serializer": "0",
-                "domelementtype": "1"
+                "dom-serializer": "0.1.1",
+                "domelementtype": "1.3.1"
             }
         },
         "dot-prop": {
@@ -4241,7 +4241,7 @@
             "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
             "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
             "requires": {
-                "is-obj": "^1.0.0"
+                "is-obj": "1.0.1"
             }
         },
         "dotenv": {
@@ -4260,10 +4260,10 @@
             "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
             "dev": true,
             "requires": {
-                "end-of-stream": "^1.0.0",
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.0.0",
-                "stream-shift": "^1.0.0"
+                "end-of-stream": "1.4.1",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "stream-shift": "1.0.0"
             }
         },
         "dynamic-dedupe": {
@@ -4272,7 +4272,7 @@
             "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=",
             "dev": true,
             "requires": {
-                "xtend": "^4.0.0"
+                "xtend": "4.0.2"
             }
         },
         "ecc-jsbn": {
@@ -4280,8 +4280,8 @@
             "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
             "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
             "requires": {
-                "jsbn": "~0.1.0",
-                "safer-buffer": "^2.1.0"
+                "jsbn": "0.1.1",
+                "safer-buffer": "2.1.2"
             }
         },
         "ecdsa-sig-formatter": {
@@ -4289,7 +4289,7 @@
             "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
             "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
             "requires": {
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "ee-first": {
@@ -4307,21 +4307,20 @@
             "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz",
             "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
             "requires": {
-                "bn.js": "^4.4.0",
-                "brorand": "^1.0.1",
-                "hash.js": "^1.0.0",
-                "hmac-drbg": "^1.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.0"
+                "bn.js": "4.11.8",
+                "brorand": "1.1.0",
+                "hash.js": "1.1.7",
+                "hmac-drbg": "1.0.1",
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1",
+                "minimalistic-crypto-utils": "1.0.1"
             }
         },
         "emit-logger": {
             "version": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070",
-            "from": "github:chocolateboy/emit-logger#better-emitter-name",
             "requires": {
-                "chalk": "^1.1.1",
-                "moment": "^2.10.6"
+                "chalk": "1.1.3",
+                "moment": "2.24.0"
             }
         },
         "emoji-regex": {
@@ -4339,8 +4338,8 @@
             "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.23.tgz",
             "integrity": "sha512-H/x+5rJUnSvI0rdYsAFyDfuQwE0poZgTMj5TQsKirLzyHVWqs6CiUponsdE86sisXw0vS60j91HAbidJJeDt1g==",
             "requires": {
-                "babel-plugin-emotion": "^10.0.23",
-                "create-emotion": "^10.0.14"
+                "babel-plugin-emotion": "10.0.23",
+                "create-emotion": "10.0.14"
             }
         },
         "encodeurl": {
@@ -4353,7 +4352,7 @@
             "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
             "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
             "requires": {
-                "iconv-lite": "~0.4.13"
+                "iconv-lite": "0.4.24"
             }
         },
         "end-of-stream": {
@@ -4361,7 +4360,7 @@
             "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
             "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
             "requires": {
-                "once": "^1.4.0"
+                "once": "1.4.0"
             }
         },
         "engine.io": {
@@ -4369,12 +4368,12 @@
             "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz",
             "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==",
             "requires": {
-                "accepts": "~1.3.4",
+                "accepts": "1.3.7",
                 "base64id": "1.0.0",
                 "cookie": "0.3.1",
-                "debug": "~3.1.0",
-                "engine.io-parser": "~2.1.0",
-                "ws": "~6.1.0"
+                "debug": "3.1.0",
+                "engine.io-parser": "2.1.3",
+                "ws": "6.1.4"
             },
             "dependencies": {
                 "debug": {
@@ -4394,14 +4393,14 @@
             "requires": {
                 "component-emitter": "1.2.1",
                 "component-inherit": "0.0.3",
-                "debug": "~3.1.0",
-                "engine.io-parser": "~2.1.1",
+                "debug": "3.1.0",
+                "engine.io-parser": "2.1.3",
                 "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",
+                "ws": "6.1.4",
+                "xmlhttprequest-ssl": "1.5.5",
                 "yeast": "0.1.2"
             },
             "dependencies": {
@@ -4426,10 +4425,10 @@
             "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
             "requires": {
                 "after": "0.8.2",
-                "arraybuffer.slice": "~0.0.7",
+                "arraybuffer.slice": "0.0.7",
                 "base64-arraybuffer": "0.1.5",
                 "blob": "0.0.5",
-                "has-binary2": "~1.0.2"
+                "has-binary2": "1.0.3"
             }
         },
         "enhanced-resolve": {
@@ -4438,9 +4437,9 @@
             "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
             "dev": true,
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "memory-fs": "^0.4.0",
-                "tapable": "^1.0.0"
+                "graceful-fs": "4.2.0",
+                "memory-fs": "0.4.1",
+                "tapable": "1.1.3"
             }
         },
         "entities": {
@@ -4453,8 +4452,8 @@
             "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz",
             "integrity": "sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=",
             "requires": {
-                "jstransform": "^11.0.3",
-                "through": "~2.3.4"
+                "jstransform": "11.0.3",
+                "through": "2.3.8"
             }
         },
         "errno": {
@@ -4463,7 +4462,7 @@
             "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
             "dev": true,
             "requires": {
-                "prr": "~1.0.1"
+                "prr": "1.0.1"
             }
         },
         "error-ex": {
@@ -4471,7 +4470,7 @@
             "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
             "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
             "requires": {
-                "is-arrayish": "^0.2.1"
+                "is-arrayish": "0.2.1"
             }
         },
         "es-abstract": {
@@ -4479,16 +4478,16 @@
             "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz",
             "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==",
             "requires": {
-                "es-to-primitive": "^1.2.0",
-                "function-bind": "^1.1.1",
-                "has": "^1.0.3",
-                "has-symbols": "^1.0.0",
-                "is-callable": "^1.1.4",
-                "is-regex": "^1.0.4",
-                "object-inspect": "^1.6.0",
-                "object-keys": "^1.1.1",
-                "string.prototype.trimleft": "^2.1.0",
-                "string.prototype.trimright": "^2.1.0"
+                "es-to-primitive": "1.2.0",
+                "function-bind": "1.1.1",
+                "has": "1.0.3",
+                "has-symbols": "1.0.0",
+                "is-callable": "1.1.4",
+                "is-regex": "1.0.4",
+                "object-inspect": "1.6.0",
+                "object-keys": "1.1.1",
+                "string.prototype.trimleft": "2.1.0",
+                "string.prototype.trimright": "2.1.0"
             }
         },
         "es-to-primitive": {
@@ -4496,9 +4495,9 @@
             "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
             "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
             "requires": {
-                "is-callable": "^1.1.4",
-                "is-date-object": "^1.0.1",
-                "is-symbol": "^1.0.2"
+                "is-callable": "1.1.4",
+                "is-date-object": "1.0.1",
+                "is-symbol": "1.0.2"
             }
         },
         "es5-ext": {
@@ -4507,9 +4506,9 @@
             "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==",
             "dev": true,
             "requires": {
-                "es6-iterator": "~2.0.3",
-                "es6-symbol": "~3.1.1",
-                "next-tick": "^1.0.0"
+                "es6-iterator": "2.0.3",
+                "es6-symbol": "3.1.1",
+                "next-tick": "1.0.0"
             }
         },
         "es6-iterator": {
@@ -4518,9 +4517,9 @@
             "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
             "dev": true,
             "requires": {
-                "d": "1",
-                "es5-ext": "^0.10.35",
-                "es6-symbol": "^3.1.1"
+                "d": "1.0.1",
+                "es5-ext": "0.10.50",
+                "es6-symbol": "3.1.1"
             }
         },
         "es6-promise": {
@@ -4533,7 +4532,7 @@
             "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
             "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
             "requires": {
-                "es6-promise": "^4.0.3"
+                "es6-promise": "4.2.8"
             },
             "dependencies": {
                 "es6-promise": {
@@ -4549,8 +4548,8 @@
             "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
             "dev": true,
             "requires": {
-                "d": "1",
-                "es5-ext": "~0.10.14"
+                "d": "1.0.1",
+                "es5-ext": "0.10.50"
             }
         },
         "escape-html": {
@@ -4569,11 +4568,11 @@
             "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
             "dev": true,
             "requires": {
-                "esprima": "^3.1.3",
-                "estraverse": "^4.2.0",
-                "esutils": "^2.0.2",
-                "optionator": "^0.8.1",
-                "source-map": "~0.6.1"
+                "esprima": "3.1.3",
+                "estraverse": "4.2.0",
+                "esutils": "2.0.2",
+                "optionator": "0.8.2",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "esprima": {
@@ -4597,8 +4596,8 @@
             "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
             "dev": true,
             "requires": {
-                "esrecurse": "^4.1.0",
-                "estraverse": "^4.1.1"
+                "esrecurse": "4.2.1",
+                "estraverse": "4.2.0"
             }
         },
         "esprima": {
@@ -4612,7 +4611,7 @@
             "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
             "dev": true,
             "requires": {
-                "estraverse": "^4.1.0"
+                "estraverse": "4.2.0"
             }
         },
         "estraverse": {
@@ -4658,7 +4657,7 @@
             "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
             "dev": true,
             "requires": {
-                "original": "^1.0.0"
+                "original": "1.0.2"
             }
         },
         "evp_bytestokey": {
@@ -4666,8 +4665,8 @@
             "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
             "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
             "requires": {
-                "md5.js": "^1.3.4",
-                "safe-buffer": "^5.1.1"
+                "md5.js": "1.3.5",
+                "safe-buffer": "5.1.2"
             }
         },
         "execa": {
@@ -4675,13 +4674,13 @@
             "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
             "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
             "requires": {
-                "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"
+                "cross-spawn": "5.1.0",
+                "get-stream": "3.0.0",
+                "is-stream": "1.1.0",
+                "npm-run-path": "2.0.2",
+                "p-finally": "1.0.0",
+                "signal-exit": "3.0.2",
+                "strip-eof": "1.0.0"
             },
             "dependencies": {
                 "cross-spawn": {
@@ -4689,9 +4688,9 @@
                     "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
                     "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
                     "requires": {
-                        "lru-cache": "^4.0.1",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "lru-cache": "4.1.5",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     }
                 }
             }
@@ -4706,7 +4705,7 @@
             "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
             "integrity": "sha1-YKYmaAdlQst+T1cZnUrG830sX0o=",
             "requires": {
-                "debug": "^2.2"
+                "debug": "2.6.9"
             }
         },
         "expand-brackets": {
@@ -4714,13 +4713,13 @@
             "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
             "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
             "requires": {
-                "debug": "^2.3.3",
-                "define-property": "^0.2.5",
-                "extend-shallow": "^2.0.1",
-                "posix-character-classes": "^0.1.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "debug": "2.6.9",
+                "define-property": "0.2.5",
+                "extend-shallow": "2.0.1",
+                "posix-character-classes": "0.1.1",
+                "regex-not": "1.0.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "define-property": {
@@ -4728,7 +4727,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "extend-shallow": {
@@ -4736,7 +4735,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -4752,7 +4751,7 @@
             "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
             "dev": true,
             "requires": {
-                "homedir-polyfill": "^1.0.1"
+                "homedir-polyfill": "1.0.3"
             }
         },
         "express": {
@@ -4760,36 +4759,36 @@
             "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
             "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
             "requires": {
-                "accepts": "~1.3.7",
+                "accepts": "1.3.7",
                 "array-flatten": "1.1.1",
                 "body-parser": "1.19.0",
                 "content-disposition": "0.5.3",
-                "content-type": "~1.0.4",
+                "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",
+                "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",
+                "methods": "1.1.2",
+                "on-finished": "2.3.0",
+                "parseurl": "1.3.3",
                 "path-to-regexp": "0.1.7",
-                "proxy-addr": "~2.0.5",
+                "proxy-addr": "2.0.5",
                 "qs": "6.7.0",
-                "range-parser": "~1.2.1",
+                "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",
+                "statuses": "1.5.0",
+                "type-is": "1.6.18",
                 "utils-merge": "1.0.1",
-                "vary": "~1.1.2"
+                "vary": "1.1.2"
             },
             "dependencies": {
                 "cookie": {
@@ -4804,7 +4803,7 @@
             "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
             "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
             "requires": {
-                "connect-flash": "0.1.x"
+                "connect-flash": "0.1.1"
             }
         },
         "express-session": {
@@ -4815,11 +4814,11 @@
                 "cookie": "0.3.1",
                 "cookie-signature": "1.0.6",
                 "debug": "2.6.9",
-                "depd": "~2.0.0",
-                "on-headers": "~1.0.2",
-                "parseurl": "~1.3.3",
+                "depd": "2.0.0",
+                "on-headers": "1.0.2",
+                "parseurl": "1.3.3",
                 "safe-buffer": "5.1.2",
-                "uid-safe": "~2.1.5"
+                "uid-safe": "2.1.5"
             },
             "dependencies": {
                 "depd": {
@@ -4834,8 +4833,8 @@
             "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-5.3.1.tgz",
             "integrity": "sha512-g8xkipBF6VxHbO1+ksC7nxUU7+pWif0+OZXjZTybKJ/V0aTVhuCoHbyhIPgSYVldwQLocGExPtB2pE0DqK4jsw==",
             "requires": {
-                "lodash": "^4.17.10",
-                "validator": "^10.4.0"
+                "lodash": "4.17.15",
+                "validator": "10.11.0"
             }
         },
         "expressjs": {
@@ -4853,8 +4852,8 @@
             "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
             "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
             "requires": {
-                "assign-symbols": "^1.0.0",
-                "is-extendable": "^1.0.1"
+                "assign-symbols": "1.0.0",
+                "is-extendable": "1.0.1"
             },
             "dependencies": {
                 "is-extendable": {
@@ -4862,7 +4861,7 @@
                     "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
                     "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
                     "requires": {
-                        "is-plain-object": "^2.0.4"
+                        "is-plain-object": "2.0.4"
                     }
                 }
             }
@@ -4872,14 +4871,14 @@
             "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
             "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
             "requires": {
-                "array-unique": "^0.3.2",
-                "define-property": "^1.0.0",
-                "expand-brackets": "^2.1.4",
-                "extend-shallow": "^2.0.1",
-                "fragment-cache": "^0.2.1",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "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.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "define-property": {
@@ -4887,7 +4886,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "extend-shallow": {
@@ -4895,7 +4894,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -4903,7 +4902,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -4911,7 +4910,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -4919,9 +4918,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -4958,7 +4957,7 @@
             "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
             "dev": true,
             "requires": {
-                "websocket-driver": ">=0.5.1"
+                "websocket-driver": "0.7.3"
             }
         },
         "fbjs": {
@@ -4966,13 +4965,13 @@
             "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
             "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
             "requires": {
-                "core-js": "^1.0.0",
-                "isomorphic-fetch": "^2.1.1",
-                "loose-envify": "^1.0.0",
-                "object-assign": "^4.1.0",
-                "promise": "^7.1.1",
-                "setimmediate": "^1.0.5",
-                "ua-parser-js": "^0.7.18"
+                "core-js": "1.2.7",
+                "isomorphic-fetch": "2.2.1",
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "promise": "7.3.1",
+                "setimmediate": "1.0.5",
+                "ua-parser-js": "0.7.20"
             }
         },
         "figgy-pudding": {
@@ -4987,8 +4986,8 @@
             "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.0.2",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -4997,9 +4996,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -5010,7 +5009,7 @@
             "integrity": "sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ=",
             "dev": true,
             "requires": {
-                "debounce": "^1.0.0"
+                "debounce": "1.2.0"
             }
         },
         "fill-range": {
@@ -5018,10 +5017,10 @@
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
             "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
             "requires": {
-                "extend-shallow": "^2.0.1",
-                "is-number": "^3.0.0",
-                "repeat-string": "^1.6.1",
-                "to-regex-range": "^2.1.0"
+                "extend-shallow": "2.0.1",
+                "is-number": "3.0.0",
+                "repeat-string": "1.6.1",
+                "to-regex-range": "2.1.1"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -5029,7 +5028,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -5040,12 +5039,12 @@
             "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
             "requires": {
                 "debug": "2.6.9",
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "on-finished": "~2.3.0",
-                "parseurl": "~1.3.3",
-                "statuses": "~1.5.0",
-                "unpipe": "~1.0.0"
+                "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"
             }
         },
         "find": {
@@ -5053,7 +5052,7 @@
             "resolved": "https://registry.npmjs.org/find/-/find-0.1.7.tgz",
             "integrity": "sha1-yGyHrxqxjyIrvjjeyGy8dg0Wpvs=",
             "requires": {
-                "traverse-chain": "~0.1.0"
+                "traverse-chain": "0.1.0"
             }
         },
         "find-cache-dir": {
@@ -5062,9 +5061,9 @@
             "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
             "dev": true,
             "requires": {
-                "commondir": "^1.0.1",
-                "make-dir": "^1.0.0",
-                "pkg-dir": "^2.0.0"
+                "commondir": "1.0.1",
+                "make-dir": "1.3.0",
+                "pkg-dir": "2.0.0"
             }
         },
         "find-in-files": {
@@ -5072,8 +5071,8 @@
             "resolved": "https://registry.npmjs.org/find-in-files/-/find-in-files-0.5.0.tgz",
             "integrity": "sha512-VraTc6HdtdSHmAp0yJpAy20yPttGKzyBWc7b7FPnnsX9TOgmKx0g9xajizpF/iuu4IvNK4TP0SpyBT9zAlwG+g==",
             "requires": {
-                "find": "^0.1.5",
-                "q": "^1.0.1"
+                "find": "0.1.7",
+                "q": "1.5.1"
             }
         },
         "find-root": {
@@ -5086,7 +5085,7 @@
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
             "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
             "requires": {
-                "locate-path": "^2.0.0"
+                "locate-path": "2.0.0"
             }
         },
         "findup-sync": {
@@ -5095,10 +5094,10 @@
             "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
             "dev": true,
             "requires": {
-                "detect-file": "^1.0.0",
-                "is-glob": "^4.0.0",
-                "micromatch": "^3.0.4",
-                "resolve-dir": "^1.0.1"
+                "detect-file": "1.0.0",
+                "is-glob": "4.0.1",
+                "micromatch": "3.1.10",
+                "resolve-dir": "1.0.1"
             }
         },
         "flat": {
@@ -5106,7 +5105,7 @@
             "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
             "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
             "requires": {
-                "is-buffer": "~2.0.3"
+                "is-buffer": "2.0.4"
             },
             "dependencies": {
                 "is-buffer": {
@@ -5127,8 +5126,8 @@
             "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.3.6"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "follow-redirects": {
@@ -5137,7 +5136,7 @@
             "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
             "dev": true,
             "requires": {
-                "debug": "^3.2.6"
+                "debug": "3.2.6"
             },
             "dependencies": {
                 "debug": {
@@ -5146,7 +5145,7 @@
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -5167,7 +5166,7 @@
             "resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz",
             "integrity": "sha1-z6hXrsFCLh0Sb/CHhPz2Jim8g/Y=",
             "requires": {
-                "get-prototype-chain": "^1.0.1"
+                "get-prototype-chain": "1.0.1"
             }
         },
         "for-each-property-deep": {
@@ -5189,7 +5188,7 @@
             "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
             "dev": true,
             "requires": {
-                "for-in": "^1.0.1"
+                "for-in": "1.0.2"
             }
         },
         "forever-agent": {
@@ -5203,14 +5202,14 @@
             "integrity": "sha512-srf43Z3B1hCJNrwCG78DbHmWgKQUqHKsvFbLP182gank28j9s05KJbSZaMKBA0b6Pqi0LBLpAFWeB0JPbc1iLQ==",
             "dev": true,
             "requires": {
-                "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"
+                "babel-code-frame": "6.26.0",
+                "chalk": "2.4.2",
+                "chokidar": "2.1.6",
+                "micromatch": "3.1.10",
+                "minimatch": "3.0.4",
+                "semver": "5.7.0",
+                "tapable": "1.1.3",
+                "worker-rpc": "0.1.1"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -5219,7 +5218,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -5228,9 +5227,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -5239,7 +5238,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -5249,9 +5248,9 @@
             "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.0.tgz",
             "integrity": "sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==",
             "requires": {
-                "asynckit": "^0.4.0",
-                "combined-stream": "^1.0.6",
-                "mime-types": "^2.1.12"
+                "asynckit": "0.4.0",
+                "combined-stream": "1.0.8",
+                "mime-types": "2.1.24"
             }
         },
         "formidable": {
@@ -5269,7 +5268,7 @@
             "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
             "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
             "requires": {
-                "map-cache": "^0.2.2"
+                "map-cache": "0.2.2"
             }
         },
         "fresh": {
@@ -5283,8 +5282,8 @@
             "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.0.0"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "fs-constants": {
@@ -5302,11 +5301,11 @@
             "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
             "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "jsonfile": "^2.1.0",
-                "klaw": "^1.0.0",
-                "path-is-absolute": "^1.0.0",
-                "rimraf": "^2.2.8"
+                "graceful-fs": "4.2.0",
+                "jsonfile": "2.4.0",
+                "klaw": "1.3.1",
+                "path-is-absolute": "1.0.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "rimraf": {
@@ -5314,7 +5313,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -5324,7 +5323,7 @@
             "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz",
             "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==",
             "requires": {
-                "minipass": "^2.2.1"
+                "minipass": "2.3.5"
             }
         },
         "fs-write-stream-atomic": {
@@ -5333,10 +5332,10 @@
             "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
             "dev": true,
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "iferr": "^0.1.5",
-                "imurmurhash": "^0.1.4",
-                "readable-stream": "1 || 2"
+                "graceful-fs": "4.2.0",
+                "iferr": "0.1.5",
+                "imurmurhash": "0.1.4",
+                "readable-stream": "2.3.6"
             }
         },
         "fs.realpath": {
@@ -5350,8 +5349,8 @@
             "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
             "optional": true,
             "requires": {
-                "nan": "^2.12.1",
-                "node-pre-gyp": "^0.12.0"
+                "nan": "2.14.0",
+                "node-pre-gyp": "0.12.0"
             },
             "dependencies": {
                 "abbrev": {
@@ -5373,8 +5372,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "delegates": "^1.0.0",
-                        "readable-stream": "^2.0.6"
+                        "delegates": "1.0.0",
+                        "readable-stream": "2.3.6"
                     }
                 },
                 "balanced-match": {
@@ -5385,7 +5384,7 @@
                     "version": "1.1.11",
                     "bundled": true,
                     "requires": {
-                        "balanced-match": "^1.0.0",
+                        "balanced-match": "1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
@@ -5416,7 +5415,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.1"
                     }
                 },
                 "deep-extend": {
@@ -5439,7 +5438,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minipass": "^2.2.1"
+                        "minipass": "2.3.5"
                     }
                 },
                 "fs.realpath": {
@@ -5452,14 +5451,14 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "aproba": "^1.0.3",
-                        "console-control-strings": "^1.0.0",
-                        "has-unicode": "^2.0.0",
-                        "object-assign": "^4.1.0",
-                        "signal-exit": "^3.0.0",
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1",
-                        "wide-align": "^1.1.0"
+                        "aproba": "1.2.0",
+                        "console-control-strings": "1.1.0",
+                        "has-unicode": "2.0.1",
+                        "object-assign": "4.1.1",
+                        "signal-exit": "3.0.2",
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1",
+                        "wide-align": "1.1.3"
                     }
                 },
                 "glob": {
@@ -5467,12 +5466,12 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "has-unicode": {
@@ -5485,7 +5484,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "safer-buffer": ">= 2.1.2 < 3"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "ignore-walk": {
@@ -5493,7 +5492,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minimatch": "^3.0.4"
+                        "minimatch": "3.0.4"
                     }
                 },
                 "inflight": {
@@ -5501,8 +5500,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "once": "^1.3.0",
-                        "wrappy": "1"
+                        "once": "1.4.0",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "inherits": {
@@ -5518,7 +5517,7 @@
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "number-is-nan": "^1.0.0"
+                        "number-is-nan": "1.0.1"
                     }
                 },
                 "isarray": {
@@ -5530,7 +5529,7 @@
                     "version": "3.0.4",
                     "bundled": true,
                     "requires": {
-                        "brace-expansion": "^1.1.7"
+                        "brace-expansion": "1.1.11"
                     }
                 },
                 "minimist": {
@@ -5541,8 +5540,8 @@
                     "version": "2.3.5",
                     "bundled": true,
                     "requires": {
-                        "safe-buffer": "^5.1.2",
-                        "yallist": "^3.0.0"
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.0.3"
                     }
                 },
                 "minizlib": {
@@ -5550,7 +5549,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minipass": "^2.2.1"
+                        "minipass": "2.3.5"
                     }
                 },
                 "mkdirp": {
@@ -5570,9 +5569,9 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "debug": "^4.1.0",
-                        "iconv-lite": "^0.4.4",
-                        "sax": "^1.2.4"
+                        "debug": "4.1.1",
+                        "iconv-lite": "0.4.24",
+                        "sax": "1.2.4"
                     }
                 },
                 "node-pre-gyp": {
@@ -5580,16 +5579,16 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "detect-libc": "^1.0.2",
-                        "mkdirp": "^0.5.1",
-                        "needle": "^2.2.1",
-                        "nopt": "^4.0.1",
-                        "npm-packlist": "^1.1.6",
-                        "npmlog": "^4.0.2",
-                        "rc": "^1.2.7",
-                        "rimraf": "^2.6.1",
-                        "semver": "^5.3.0",
-                        "tar": "^4"
+                        "detect-libc": "1.0.3",
+                        "mkdirp": "0.5.1",
+                        "needle": "2.3.0",
+                        "nopt": "4.0.1",
+                        "npm-packlist": "1.4.1",
+                        "npmlog": "4.1.2",
+                        "rc": "1.2.8",
+                        "rimraf": "2.6.3",
+                        "semver": "5.7.0",
+                        "tar": "4.4.8"
                     }
                 },
                 "nopt": {
@@ -5597,8 +5596,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "abbrev": "1",
-                        "osenv": "^0.1.4"
+                        "abbrev": "1.1.1",
+                        "osenv": "0.1.5"
                     }
                 },
                 "npm-bundled": {
@@ -5611,8 +5610,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "ignore-walk": "^3.0.1",
-                        "npm-bundled": "^1.0.1"
+                        "ignore-walk": "3.0.1",
+                        "npm-bundled": "1.0.6"
                     }
                 },
                 "npmlog": {
@@ -5620,10 +5619,10 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "are-we-there-yet": "~1.1.2",
-                        "console-control-strings": "~1.1.0",
-                        "gauge": "~2.7.3",
-                        "set-blocking": "~2.0.0"
+                        "are-we-there-yet": "1.1.5",
+                        "console-control-strings": "1.1.0",
+                        "gauge": "2.7.4",
+                        "set-blocking": "2.0.0"
                     }
                 },
                 "number-is-nan": {
@@ -5639,7 +5638,7 @@
                     "version": "1.4.0",
                     "bundled": true,
                     "requires": {
-                        "wrappy": "1"
+                        "wrappy": "1.0.2"
                     }
                 },
                 "os-homedir": {
@@ -5657,8 +5656,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "os-homedir": "^1.0.0",
-                        "os-tmpdir": "^1.0.0"
+                        "os-homedir": "1.0.2",
+                        "os-tmpdir": "1.0.2"
                     }
                 },
                 "path-is-absolute": {
@@ -5676,10 +5675,10 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "deep-extend": "^0.6.0",
-                        "ini": "~1.3.0",
-                        "minimist": "^1.2.0",
-                        "strip-json-comments": "~2.0.1"
+                        "deep-extend": "0.6.0",
+                        "ini": "1.3.5",
+                        "minimist": "1.2.0",
+                        "strip-json-comments": "2.0.1"
                     },
                     "dependencies": {
                         "minimist": {
@@ -5694,13 +5693,13 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "core-util-is": "~1.0.0",
-                        "inherits": "~2.0.3",
-                        "isarray": "~1.0.0",
-                        "process-nextick-args": "~2.0.0",
-                        "safe-buffer": "~5.1.1",
-                        "string_decoder": "~1.1.1",
-                        "util-deprecate": "~1.0.1"
+                        "core-util-is": "1.0.2",
+                        "inherits": "2.0.3",
+                        "isarray": "1.0.0",
+                        "process-nextick-args": "2.0.0",
+                        "safe-buffer": "5.1.2",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "rimraf": {
@@ -5708,7 +5707,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.3"
                     }
                 },
                 "safe-buffer": {
@@ -5744,9 +5743,9 @@
                     "version": "1.0.2",
                     "bundled": true,
                     "requires": {
-                        "code-point-at": "^1.0.0",
-                        "is-fullwidth-code-point": "^1.0.0",
-                        "strip-ansi": "^3.0.0"
+                        "code-point-at": "1.1.0",
+                        "is-fullwidth-code-point": "1.0.0",
+                        "strip-ansi": "3.0.1"
                     }
                 },
                 "string_decoder": {
@@ -5754,14 +5753,14 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "strip-ansi": {
                     "version": "3.0.1",
                     "bundled": true,
                     "requires": {
-                        "ansi-regex": "^2.0.0"
+                        "ansi-regex": "2.1.1"
                     }
                 },
                 "strip-json-comments": {
@@ -5774,13 +5773,13 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "chownr": "^1.1.1",
-                        "fs-minipass": "^1.2.5",
-                        "minipass": "^2.3.4",
-                        "minizlib": "^1.1.1",
-                        "mkdirp": "^0.5.0",
-                        "safe-buffer": "^5.1.2",
-                        "yallist": "^3.0.2"
+                        "chownr": "1.1.1",
+                        "fs-minipass": "1.2.5",
+                        "minipass": "2.3.5",
+                        "minizlib": "1.2.1",
+                        "mkdirp": "0.5.1",
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.0.3"
                     }
                 },
                 "util-deprecate": {
@@ -5793,7 +5792,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "string-width": "^1.0.2 || 2"
+                        "string-width": "1.0.2"
                     }
                 },
                 "wrappy": {
@@ -5811,10 +5810,10 @@
             "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
             "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "inherits": "~2.0.0",
-                "mkdirp": ">=0.5 0",
-                "rimraf": "2"
+                "graceful-fs": "4.2.0",
+                "inherits": "2.0.3",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "rimraf": {
@@ -5822,7 +5821,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -5837,14 +5836,14 @@
             "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
             "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
             "requires": {
-                "aproba": "^1.0.3",
-                "console-control-strings": "^1.0.0",
-                "has-unicode": "^2.0.0",
-                "object-assign": "^4.1.0",
-                "signal-exit": "^3.0.0",
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1",
-                "wide-align": "^1.1.0"
+                "aproba": "1.2.0",
+                "console-control-strings": "1.1.0",
+                "has-unicode": "2.0.1",
+                "object-assign": "4.1.1",
+                "signal-exit": "3.0.2",
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wide-align": "1.1.3"
             }
         },
         "gaxios": {
@@ -5852,10 +5851,10 @@
             "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.0.1.tgz",
             "integrity": "sha512-c1NXovTxkgRJTIgB2FrFmOFg4YIV6N/bAa4f/FZ4jIw13Ql9ya/82x69CswvotJhbV3DiGnlTZwoq2NVXk2Irg==",
             "requires": {
-                "abort-controller": "^3.0.0",
-                "extend": "^3.0.2",
-                "https-proxy-agent": "^2.2.1",
-                "node-fetch": "^2.3.0"
+                "abort-controller": "3.0.0",
+                "extend": "3.0.2",
+                "https-proxy-agent": "2.2.2",
+                "node-fetch": "2.6.0"
             },
             "dependencies": {
                 "node-fetch": {
@@ -5870,7 +5869,7 @@
             "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
             "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
             "requires": {
-                "globule": "^1.0.0"
+                "globule": "1.2.1"
             }
         },
         "gcp-metadata": {
@@ -5878,8 +5877,8 @@
             "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-2.0.1.tgz",
             "integrity": "sha512-nrbLj5O1MurvpLC/doFwzdTfKnmYGDYXlY/v7eQ4tJNVIvQXbOK672J9UFbradbtmuTkyHzjpzD8HD0Djz0LWw==",
             "requires": {
-                "gaxios": "^2.0.0",
-                "json-bigint": "^0.3.0"
+                "gaxios": "2.0.1",
+                "json-bigint": "0.3.0"
             }
         },
         "get-caller-file": {
@@ -5927,7 +5926,7 @@
             "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
             "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
             "requires": {
-                "assert-plus": "^1.0.0"
+                "assert-plus": "1.0.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -5947,12 +5946,12 @@
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
             "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
             "requires": {
-                "fs.realpath": "^1.0.0",
-                "inflight": "^1.0.4",
-                "inherits": "2",
-                "minimatch": "^3.0.4",
-                "once": "^1.3.0",
-                "path-is-absolute": "^1.0.0"
+                "fs.realpath": "1.0.0",
+                "inflight": "1.0.6",
+                "inherits": "2.0.3",
+                "minimatch": "3.0.4",
+                "once": "1.4.0",
+                "path-is-absolute": "1.0.1"
             }
         },
         "glob-parent": {
@@ -5960,8 +5959,8 @@
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
             "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
             "requires": {
-                "is-glob": "^3.1.0",
-                "path-dirname": "^1.0.0"
+                "is-glob": "3.1.0",
+                "path-dirname": "1.0.2"
             },
             "dependencies": {
                 "is-glob": {
@@ -5969,7 +5968,7 @@
                     "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
                     "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
                     "requires": {
-                        "is-extglob": "^2.1.0"
+                        "is-extglob": "2.1.1"
                     }
                 }
             }
@@ -5979,7 +5978,7 @@
             "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
             "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
             "requires": {
-                "ini": "^1.3.4"
+                "ini": "1.3.5"
             }
         },
         "global-modules": {
@@ -5988,7 +5987,7 @@
             "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
             "dev": true,
             "requires": {
-                "global-prefix": "^3.0.0"
+                "global-prefix": "3.0.0"
             },
             "dependencies": {
                 "global-prefix": {
@@ -5997,9 +5996,9 @@
                     "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
                     "dev": true,
                     "requires": {
-                        "ini": "^1.3.5",
-                        "kind-of": "^6.0.2",
-                        "which": "^1.3.1"
+                        "ini": "1.3.5",
+                        "kind-of": "6.0.2",
+                        "which": "1.3.1"
                     }
                 }
             }
@@ -6010,11 +6009,11 @@
             "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
             "dev": true,
             "requires": {
-                "expand-tilde": "^2.0.2",
-                "homedir-polyfill": "^1.0.1",
-                "ini": "^1.3.4",
-                "is-windows": "^1.0.1",
-                "which": "^1.2.14"
+                "expand-tilde": "2.0.2",
+                "homedir-polyfill": "1.0.3",
+                "ini": "1.3.5",
+                "is-windows": "1.0.2",
+                "which": "1.3.1"
             }
         },
         "globby": {
@@ -6023,12 +6022,12 @@
             "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
             "dev": true,
             "requires": {
-                "array-union": "^1.0.1",
-                "dir-glob": "^2.0.0",
-                "glob": "^7.1.2",
-                "ignore": "^3.3.5",
-                "pify": "^3.0.0",
-                "slash": "^1.0.0"
+                "array-union": "1.0.2",
+                "dir-glob": "2.2.2",
+                "glob": "7.1.4",
+                "ignore": "3.3.10",
+                "pify": "3.0.0",
+                "slash": "1.0.0"
             },
             "dependencies": {
                 "pify": {
@@ -6044,9 +6043,9 @@
             "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
             "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
             "requires": {
-                "glob": "~7.1.1",
-                "lodash": "~4.17.10",
-                "minimatch": "~3.0.2"
+                "glob": "7.1.4",
+                "lodash": "4.17.15",
+                "minimatch": "3.0.4"
             }
         },
         "golden-layout": {
@@ -6054,7 +6053,7 @@
             "resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-1.5.9.tgz",
             "integrity": "sha1-o5vB9qZ+b4hreXwBbdkk6UJrp38=",
             "requires": {
-                "jquery": "*"
+                "jquery": "3.4.1"
             }
         },
         "google-auth-library": {
@@ -6062,14 +6061,14 @@
             "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-4.2.6.tgz",
             "integrity": "sha512-oJ6tCA9rbsYeIVY+mcLPFHa2hatz3XO6idYIrlI/KhhlMxZrO3tKyU8O2Pxu5KnSBBP7Wj4HtbM1LLKngNFaFw==",
             "requires": {
-                "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"
+                "arrify": "2.0.1",
+                "base64-js": "1.3.0",
+                "fast-text-encoding": "1.0.0",
+                "gaxios": "2.0.1",
+                "gcp-metadata": "2.0.1",
+                "gtoken": "3.0.2",
+                "jws": "3.2.2",
+                "lru-cache": "5.1.1"
             },
             "dependencies": {
                 "arrify": {
@@ -6082,7 +6081,7 @@
                     "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
                     "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 }
             }
@@ -6092,7 +6091,7 @@
             "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.1.tgz",
             "integrity": "sha512-6h6x+eBX3k+IDSe/c8dVYmn8Mzr1mUcmKC9MdUSwaBkFAXlqBEnwFWmSFgGC+tcqtsLn73BDP/vUNWEehf1Rww==",
             "requires": {
-                "node-forge": "^0.8.0"
+                "node-forge": "0.8.5"
             },
             "dependencies": {
                 "node-forge": {
@@ -6107,8 +6106,8 @@
             "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-40.0.1.tgz",
             "integrity": "sha512-B6qZVCautOOspEhru9GZ814I+ztkGWyA4ZEUfaXwXHBruX/HAWqedbsuUEx1w3nCECywK/FLTNUdcbH9zpaMaw==",
             "requires": {
-                "google-auth-library": "^4.0.0",
-                "googleapis-common": "^2.0.2"
+                "google-auth-library": "4.2.6",
+                "googleapis-common": "2.0.4"
             }
         },
         "googleapis-common": {
@@ -6116,12 +6115,12 @@
             "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-2.0.4.tgz",
             "integrity": "sha512-8RRkxr24v1jIKCC1onFWA8RGnwFV55m3Qpil9DLX1yLc9e5qvOJsRoDOhhD2e7jFRONYEhT/BzT8vJZANqSr9w==",
             "requires": {
-                "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"
+                "extend": "3.0.2",
+                "gaxios": "2.0.1",
+                "google-auth-library": "4.2.6",
+                "qs": "6.7.0",
+                "url-template": "2.0.8",
+                "uuid": "3.3.2"
             }
         },
         "googlephotos": {
@@ -6129,8 +6128,8 @@
             "resolved": "https://registry.npmjs.org/googlephotos/-/googlephotos-0.2.1.tgz",
             "integrity": "sha512-BCDFBGvv3CgceAc4/+AdbLebqVSYZTJx6qjoZTukQXRz86uEnR5GlYgVlVoBYqVypZS92poRRVBMVVdZhItdwg==",
             "requires": {
-                "request": "^2.86.0",
-                "request-promise": "^4.2.2"
+                "request": "2.88.0",
+                "request-promise": "4.2.4"
             },
             "dependencies": {
                 "assert-plus": {
@@ -6153,9 +6152,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -6163,8 +6162,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -6172,9 +6171,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -6192,26 +6191,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     }
                 }
             }
@@ -6221,17 +6220,17 @@
             "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
             "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
             "requires": {
-                "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"
+                "create-error-class": "3.0.2",
+                "duplexer3": "0.1.4",
+                "get-stream": "3.0.0",
+                "is-redirect": "1.0.0",
+                "is-retry-allowed": "1.1.0",
+                "is-stream": "1.1.0",
+                "lowercase-keys": "1.0.1",
+                "safe-buffer": "5.1.2",
+                "timed-out": "4.0.1",
+                "unzip-response": "2.0.1",
+                "url-parse-lax": "1.0.0"
             }
         },
         "graceful-fs": {
@@ -6255,10 +6254,10 @@
             "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-3.0.2.tgz",
             "integrity": "sha512-BOBi6Zz31JfxhSHRZBIDdbwIbOPyux10WxJHdx8wz/FMP1zyN1xFrsAWsgcLe5ww5v/OZu/MePUEZAjgJXSauA==",
             "requires": {
-                "gaxios": "^2.0.0",
-                "google-p12-pem": "^2.0.0",
-                "jws": "^3.1.5",
-                "mime": "^2.2.0"
+                "gaxios": "2.0.1",
+                "google-p12-pem": "2.0.1",
+                "jws": "3.2.2",
+                "mime": "2.4.4"
             },
             "dependencies": {
                 "mime": {
@@ -6289,8 +6288,8 @@
             "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
             "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
             "requires": {
-                "ajv": "^6.5.5",
-                "har-schema": "^2.0.0"
+                "ajv": "6.10.2",
+                "har-schema": "2.0.0"
             }
         },
         "has": {
@@ -6298,7 +6297,7 @@
             "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
             "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
             "requires": {
-                "function-bind": "^1.1.1"
+                "function-bind": "1.1.1"
             }
         },
         "has-ansi": {
@@ -6306,7 +6305,7 @@
             "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
             "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
             "requires": {
-                "ansi-regex": "^2.0.0"
+                "ansi-regex": "2.1.1"
             }
         },
         "has-binary2": {
@@ -6349,9 +6348,9 @@
             "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
             "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
             "requires": {
-                "get-value": "^2.0.6",
-                "has-values": "^1.0.0",
-                "isobject": "^3.0.0"
+                "get-value": "2.0.6",
+                "has-values": "1.0.0",
+                "isobject": "3.0.1"
             }
         },
         "has-values": {
@@ -6359,8 +6358,8 @@
             "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
             "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
             "requires": {
-                "is-number": "^3.0.0",
-                "kind-of": "^4.0.0"
+                "is-number": "3.0.0",
+                "kind-of": "4.0.0"
             },
             "dependencies": {
                 "kind-of": {
@@ -6368,7 +6367,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
                     "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -6378,8 +6377,8 @@
             "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
             "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "hash.js": {
@@ -6387,8 +6386,8 @@
             "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
             "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
             "requires": {
-                "inherits": "^2.0.3",
-                "minimalistic-assert": "^1.0.1"
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "he": {
@@ -6402,9 +6401,9 @@
             "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
             "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
             "requires": {
-                "hash.js": "^1.0.3",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.1"
+                "hash.js": "1.1.7",
+                "minimalistic-assert": "1.0.1",
+                "minimalistic-crypto-utils": "1.0.1"
             }
         },
         "hoist-non-react-statics": {
@@ -6412,7 +6411,7 @@
             "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
             "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
             "requires": {
-                "react-is": "^16.7.0"
+                "react-is": "16.8.6"
             }
         },
         "homedir-polyfill": {
@@ -6421,7 +6420,7 @@
             "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
             "dev": true,
             "requires": {
-                "parse-passwd": "^1.0.0"
+                "parse-passwd": "1.0.0"
             }
         },
         "hosted-git-info": {
@@ -6440,10 +6439,10 @@
             "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.1",
-                "obuf": "^1.0.0",
-                "readable-stream": "^2.0.1",
-                "wbuf": "^1.1.0"
+                "inherits": "2.0.3",
+                "obuf": "1.1.2",
+                "readable-stream": "2.3.6",
+                "wbuf": "1.7.3"
             }
         },
         "html-encoding-sniffer": {
@@ -6452,7 +6451,7 @@
             "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
             "dev": true,
             "requires": {
-                "whatwg-encoding": "^1.0.1"
+                "whatwg-encoding": "1.0.5"
             }
         },
         "html-entities": {
@@ -6471,12 +6470,12 @@
             "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
             "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
             "requires": {
-                "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"
+                "domelementtype": "1.3.1",
+                "domhandler": "2.4.2",
+                "domutils": "1.5.1",
+                "entities": "1.1.2",
+                "inherits": "2.0.3",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -6484,9 +6483,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -6502,10 +6501,10 @@
             "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
             "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
             "requires": {
-                "depd": "~1.1.2",
+                "depd": "1.1.2",
                 "inherits": "2.0.3",
                 "setprototypeof": "1.1.1",
-                "statuses": ">= 1.5.0 < 2",
+                "statuses": "1.5.0",
                 "toidentifier": "1.0.0"
             }
         },
@@ -6521,9 +6520,9 @@
             "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
             "dev": true,
             "requires": {
-                "eventemitter3": "^3.0.0",
-                "follow-redirects": "^1.0.0",
-                "requires-port": "^1.0.0"
+                "eventemitter3": "3.1.2",
+                "follow-redirects": "1.7.0",
+                "requires-port": "1.0.0"
             },
             "dependencies": {
                 "eventemitter3": {
@@ -6540,10 +6539,10 @@
             "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
             "dev": true,
             "requires": {
-                "http-proxy": "^1.17.0",
-                "is-glob": "^4.0.0",
-                "lodash": "^4.17.11",
-                "micromatch": "^3.1.10"
+                "http-proxy": "1.17.0",
+                "is-glob": "4.0.1",
+                "lodash": "4.17.15",
+                "micromatch": "3.1.10"
             }
         },
         "http-signature": {
@@ -6551,9 +6550,9 @@
             "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
             "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
             "requires": {
-                "assert-plus": "^1.0.0",
-                "jsprim": "^1.2.2",
-                "sshpk": "^1.7.0"
+                "assert-plus": "1.0.0",
+                "jsprim": "1.4.1",
+                "sshpk": "1.16.1"
             }
         },
         "https-browserify": {
@@ -6567,8 +6566,8 @@
             "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
             "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
             "requires": {
-                "agent-base": "^4.3.0",
-                "debug": "^3.1.0"
+                "agent-base": "4.3.0",
+                "debug": "3.2.6"
             },
             "dependencies": {
                 "debug": {
@@ -6576,7 +6575,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -6601,7 +6600,7 @@
             "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
             "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
             "requires": {
-                "safer-buffer": ">= 2.1.2 < 3"
+                "safer-buffer": "2.1.2"
             }
         },
         "icss-replace-symbols": {
@@ -6616,7 +6615,7 @@
             "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.14"
+                "postcss": "7.0.17"
             }
         },
         "ieee754": {
@@ -6646,7 +6645,7 @@
             "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
             "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
             "requires": {
-                "minimatch": "^3.0.4"
+                "minimatch": "3.0.4"
             }
         },
         "image-data-uri": {
@@ -6654,10 +6653,10 @@
             "resolved": "https://registry.npmjs.org/image-data-uri/-/image-data-uri-2.0.0.tgz",
             "integrity": "sha512-PhIJxgfSQai/Xy8Nij1lWgK6++Y6x/ga2FKQTd8F71Nz2ArqtFr1F1UAREK0twrfp7mcEqidgGSF06No14/m+Q==",
             "requires": {
-                "fs-extra": "^0.26.7",
+                "fs-extra": "0.26.7",
                 "magicli": "0.0.8",
-                "mime-types": "^2.1.18",
-                "request": "^2.88.0"
+                "mime-types": "2.1.24",
+                "request": "2.88.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -6680,9 +6679,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -6690,8 +6689,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -6699,9 +6698,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -6719,26 +6718,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     }
                 }
             }
@@ -6753,7 +6752,7 @@
             "resolved": "https://registry.npmjs.org/imagesloaded/-/imagesloaded-4.1.4.tgz",
             "integrity": "sha512-ltiBVcYpc/TYTF5nolkMNsnREHW+ICvfQ3Yla2Sgr71YFwQ86bDwV9hgpFhFtrGPuwEx5+LqOHIrdXBdoWwwsA==",
             "requires": {
-                "ev-emitter": "^1.0.0"
+                "ev-emitter": "1.1.1"
             }
         },
         "immutable": {
@@ -6766,8 +6765,8 @@
             "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
             "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
             "requires": {
-                "parent-module": "^1.0.0",
-                "resolve-from": "^4.0.0"
+                "parent-module": "1.0.1",
+                "resolve-from": "4.0.0"
             },
             "dependencies": {
                 "resolve-from": {
@@ -6788,8 +6787,8 @@
             "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
             "dev": true,
             "requires": {
-                "pkg-dir": "^3.0.0",
-                "resolve-cwd": "^2.0.0"
+                "pkg-dir": "3.0.0",
+                "resolve-cwd": "2.0.0"
             },
             "dependencies": {
                 "find-up": {
@@ -6798,7 +6797,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "locate-path": {
@@ -6807,8 +6806,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "p-locate": {
@@ -6817,7 +6816,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "pkg-dir": {
@@ -6826,7 +6825,7 @@
                     "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
                     "dev": true,
                     "requires": {
-                        "find-up": "^3.0.0"
+                        "find-up": "3.0.0"
                     }
                 }
             }
@@ -6846,7 +6845,7 @@
             "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
             "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
             "requires": {
-                "repeating": "^2.0.0"
+                "repeating": "2.0.1"
             }
         },
         "indexes-of": {
@@ -6865,8 +6864,8 @@
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
             "requires": {
-                "once": "^1.3.0",
-                "wrappy": "1"
+                "once": "1.4.0",
+                "wrappy": "1.0.2"
             }
         },
         "infobox-parser": {
@@ -6874,7 +6873,7 @@
             "resolved": "https://registry.npmjs.org/infobox-parser/-/infobox-parser-3.3.1.tgz",
             "integrity": "sha512-Aj1uF/taawGhet8cazhXz2uEDFMOqH8hnuw720wvi7Zw6bJWmA45Ta2FI9xMG5wvvo4CB6GR9S1/RUFtC6EtAg==",
             "requires": {
-                "camelcase": "^4.1.0"
+                "camelcase": "4.1.0"
             }
         },
         "inherits": {
@@ -6919,10 +6918,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -6934,7 +6933,7 @@
             "requires": {
                 "for-each-property": "0.0.4",
                 "for-each-property-deep": "0.0.3",
-                "inspect-function": "^0.3.1"
+                "inspect-function": "0.3.4"
             },
             "dependencies": {
                 "inspect-function": {
@@ -6981,10 +6980,10 @@
                             "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                             "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                             "requires": {
-                                "commander": "^2.9.0",
-                                "get-stdin": "^5.0.1",
-                                "inspect-function": "^0.2.1",
-                                "pipe-functions": "^1.2.0"
+                                "commander": "2.20.0",
+                                "get-stdin": "5.0.1",
+                                "inspect-function": "0.2.2",
+                                "pipe-functions": "1.3.0"
                             }
                         },
                         "split-skip": {
@@ -7007,8 +7006,8 @@
             "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
             "dev": true,
             "requires": {
-                "default-gateway": "^4.2.0",
-                "ipaddr.js": "^1.9.0"
+                "default-gateway": "4.2.0",
+                "ipaddr.js": "1.9.0"
             }
         },
         "interpret": {
@@ -7021,7 +7020,7 @@
             "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
             "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
             "requires": {
-                "loose-envify": "^1.0.0"
+                "loose-envify": "1.4.0"
             }
         },
         "invert-kv": {
@@ -7051,13 +7050,13 @@
             "resolved": "https://registry.npmjs.org/ipc-event-emitter/-/ipc-event-emitter-2.0.2.tgz",
             "integrity": "sha512-hJsN8zCg8MZwl5nbTutqINDO4pJPbKwmCfrTJaRLNE+5H15mJx7Mxo3pXIAi8zlh+N5xpf+PdMOQ0pbtZQvRKA==",
             "requires": {
-                "babel-runtime": "^6.22.0",
-                "bluebird": "^3.4.7",
-                "boolify-string": "^2.0.2",
+                "babel-runtime": "6.26.0",
+                "bluebird": "3.5.5",
+                "boolify-string": "2.0.2",
                 "emit-logger": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070",
-                "lodash": "^4.17.4",
-                "semver": "^5.0.3",
-                "source-map-support": "^0.5.9"
+                "lodash": "4.17.15",
+                "semver": "5.7.0",
+                "source-map-support": "0.5.12"
             }
         },
         "is-accessor-descriptor": {
@@ -7065,7 +7064,7 @@
             "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
             "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -7073,7 +7072,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -7088,7 +7087,7 @@
             "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
             "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
             "requires": {
-                "binary-extensions": "^1.0.0"
+                "binary-extensions": "1.13.1"
             }
         },
         "is-buffer": {
@@ -7106,7 +7105,7 @@
             "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
             "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
             "requires": {
-                "ci-info": "^1.5.0"
+                "ci-info": "1.6.0"
             }
         },
         "is-data-descriptor": {
@@ -7114,7 +7113,7 @@
             "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
             "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -7122,7 +7121,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -7137,9 +7136,9 @@
             "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
             "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
             "requires": {
-                "is-accessor-descriptor": "^0.1.6",
-                "is-data-descriptor": "^0.1.4",
-                "kind-of": "^5.0.0"
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
             },
             "dependencies": {
                 "kind-of": {
@@ -7154,8 +7153,8 @@
             "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
             "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
             "requires": {
-                "acorn": "~4.0.2",
-                "object-assign": "^4.0.1"
+                "acorn": "4.0.13",
+                "object-assign": "4.1.1"
             },
             "dependencies": {
                 "acorn": {
@@ -7180,7 +7179,7 @@
             "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
             "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
             "requires": {
-                "number-is-nan": "^1.0.0"
+                "number-is-nan": "1.0.1"
             }
         },
         "is-fullwidth-code-point": {
@@ -7188,7 +7187,7 @@
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
             "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
             "requires": {
-                "number-is-nan": "^1.0.0"
+                "number-is-nan": "1.0.1"
             }
         },
         "is-glob": {
@@ -7196,7 +7195,7 @@
             "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
             "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
             "requires": {
-                "is-extglob": "^2.1.1"
+                "is-extglob": "2.1.1"
             }
         },
         "is-installed-globally": {
@@ -7204,8 +7203,8 @@
             "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
             "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
             "requires": {
-                "global-dirs": "^0.1.0",
-                "is-path-inside": "^1.0.0"
+                "global-dirs": "0.1.1",
+                "is-path-inside": "1.0.1"
             }
         },
         "is-npm": {
@@ -7218,7 +7217,7 @@
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
             "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -7226,7 +7225,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -7248,7 +7247,7 @@
             "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
             "dev": true,
             "requires": {
-                "is-path-inside": "^2.1.0"
+                "is-path-inside": "2.1.0"
             },
             "dependencies": {
                 "is-path-inside": {
@@ -7257,7 +7256,7 @@
                     "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
                     "dev": true,
                     "requires": {
-                        "path-is-inside": "^1.0.2"
+                        "path-is-inside": "1.0.2"
                     }
                 }
             }
@@ -7267,7 +7266,7 @@
             "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
             "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
             "requires": {
-                "path-is-inside": "^1.0.1"
+                "path-is-inside": "1.0.2"
             }
         },
         "is-plain-object": {
@@ -7275,7 +7274,7 @@
             "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
             "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
             "requires": {
-                "isobject": "^3.0.1"
+                "isobject": "3.0.1"
             }
         },
         "is-promise": {
@@ -7293,7 +7292,7 @@
             "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
             "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
             "requires": {
-                "has": "^1.0.1"
+                "has": "1.0.3"
             }
         },
         "is-retry-allowed": {
@@ -7311,7 +7310,7 @@
             "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
             "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
             "requires": {
-                "has-symbols": "^1.0.0"
+                "has-symbols": "1.0.0"
             }
         },
         "is-typedarray": {
@@ -7355,8 +7354,8 @@
             "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
             "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
             "requires": {
-                "node-fetch": "^1.0.1",
-                "whatwg-fetch": ">=0.10.0"
+                "node-fetch": "1.7.3",
+                "whatwg-fetch": "3.0.0"
             }
         },
         "isstream": {
@@ -7369,8 +7368,8 @@
             "resolved": "https://registry.npmjs.org/its-set/-/its-set-1.2.3.tgz",
             "integrity": "sha512-UQc+xLLn+0a8KKRXRj3OS2kERK8G7zcayPpPULqZnPwuJ1hGWEO8+j0T5eycu7DKXYjezw3pyF8oV1fJkJxV5w==",
             "requires": {
-                "babel-runtime": "6.x.x",
-                "lodash.get": "^4.4.2"
+                "babel-runtime": "6.26.0",
+                "lodash.get": "4.4.2"
             }
         },
         "jquery": {
@@ -7383,7 +7382,7 @@
             "resolved": "https://registry.npmjs.org/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.1.tgz",
             "integrity": "sha1-1pcaMrRiRhC868rAkDsAFWHQXso=",
             "requires": {
-                "font-awesome": "4.x"
+                "font-awesome": "4.7.0"
             }
         },
         "js-base64": {
@@ -7411,8 +7410,8 @@
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
             "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
             "requires": {
-                "argparse": "^1.0.7",
-                "esprima": "^4.0.0"
+                "argparse": "1.0.10",
+                "esprima": "4.0.1"
             }
         },
         "jsbn": {
@@ -7426,32 +7425,32 @@
             "integrity": "sha512-cQZRBB33arrDAeCrAEWn1U3SvrvC8XysBua9Oqg1yWrsY/gYcusloJC3RZJXuY5eehSCmws8f2YeliCqGSkrtQ==",
             "dev": true,
             "requires": {
-                "abab": "^2.0.0",
-                "acorn": "^6.1.1",
-                "acorn-globals": "^4.3.2",
-                "array-equal": "^1.0.0",
-                "cssom": "^0.3.6",
-                "cssstyle": "^1.2.2",
-                "data-urls": "^1.1.0",
-                "domexception": "^1.0.1",
-                "escodegen": "^1.11.1",
-                "html-encoding-sniffer": "^1.0.2",
-                "nwsapi": "^2.1.4",
+                "abab": "2.0.0",
+                "acorn": "6.2.1",
+                "acorn-globals": "4.3.2",
+                "array-equal": "1.0.0",
+                "cssom": "0.3.8",
+                "cssstyle": "1.4.0",
+                "data-urls": "1.1.0",
+                "domexception": "1.0.1",
+                "escodegen": "1.11.1",
+                "html-encoding-sniffer": "1.0.2",
+                "nwsapi": "2.1.4",
                 "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"
+                "pn": "1.1.0",
+                "request": "2.88.0",
+                "request-promise-native": "1.0.7",
+                "saxes": "3.1.11",
+                "symbol-tree": "3.2.4",
+                "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.1.1",
+                "xml-name-validator": "3.0.0"
             },
             "dependencies": {
                 "acorn": {
@@ -7466,8 +7465,8 @@
                     "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==",
                     "dev": true,
                     "requires": {
-                        "acorn": "^6.0.1",
-                        "acorn-walk": "^6.0.1"
+                        "acorn": "6.2.1",
+                        "acorn-walk": "6.2.0"
                     }
                 },
                 "assert-plus": {
@@ -7494,9 +7493,9 @@
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "dev": true,
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -7505,8 +7504,8 @@
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -7515,9 +7514,9 @@
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "dev": true,
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -7538,26 +7537,26 @@
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "dev": true,
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     },
                     "dependencies": {
                         "punycode": {
@@ -7572,8 +7571,8 @@
                             "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
                             "dev": true,
                             "requires": {
-                                "psl": "^1.1.24",
-                                "punycode": "^1.4.1"
+                                "psl": "1.2.0",
+                                "punycode": "1.4.1"
                             }
                         }
                     }
@@ -7584,9 +7583,9 @@
                     "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
                     "dev": true,
                     "requires": {
-                        "ip-regex": "^2.1.0",
-                        "psl": "^1.1.28",
-                        "punycode": "^2.1.1"
+                        "ip-regex": "2.1.0",
+                        "psl": "1.2.0",
+                        "punycode": "2.1.1"
                     }
                 },
                 "ws": {
@@ -7595,7 +7594,7 @@
                     "integrity": "sha512-o41D/WmDeca0BqYhsr3nJzQyg9NF5X8l/UdnFNux9cS3lwB+swm8qGWX5rn+aD6xfBU3rGmtHij7g7x6LxFU3A==",
                     "dev": true,
                     "requires": {
-                        "async-limiter": "^1.0.0"
+                        "async-limiter": "1.0.0"
                     }
                 }
             }
@@ -7605,7 +7604,7 @@
             "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
             "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
             "requires": {
-                "bignumber.js": "^7.0.0"
+                "bignumber.js": "7.2.1"
             }
         },
         "json-parse-better-errors": {
@@ -7644,7 +7643,7 @@
             "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
             "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
             "requires": {
-                "minimist": "^1.2.0"
+                "minimist": "1.2.0"
             },
             "dependencies": {
                 "minimist": {
@@ -7659,7 +7658,7 @@
             "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
             "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
             "requires": {
-                "graceful-fs": "^4.1.6"
+                "graceful-fs": "4.2.0"
             }
         },
         "jsonschema": {
@@ -7672,16 +7671,16 @@
             "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
             "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
             "requires": {
-                "jws": "^3.2.2",
-                "lodash.includes": "^4.3.0",
-                "lodash.isboolean": "^3.0.3",
-                "lodash.isinteger": "^4.0.4",
-                "lodash.isnumber": "^3.0.3",
-                "lodash.isplainobject": "^4.0.6",
-                "lodash.isstring": "^4.0.1",
-                "lodash.once": "^4.0.0",
-                "ms": "^2.1.1",
-                "semver": "^5.6.0"
+                "jws": "3.2.2",
+                "lodash.includes": "4.3.0",
+                "lodash.isboolean": "3.0.3",
+                "lodash.isinteger": "4.0.4",
+                "lodash.isnumber": "3.0.3",
+                "lodash.isplainobject": "4.0.6",
+                "lodash.isstring": "4.0.1",
+                "lodash.once": "4.1.1",
+                "ms": "2.1.2",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "ms": {
@@ -7714,11 +7713,11 @@
             "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz",
             "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=",
             "requires": {
-                "base62": "^1.1.0",
-                "commoner": "^0.10.1",
-                "esprima-fb": "^15001.1.0-dev-harmony-fb",
-                "object-assign": "^2.0.0",
-                "source-map": "^0.4.2"
+                "base62": "1.2.8",
+                "commoner": "0.10.8",
+                "esprima-fb": "15001.1.0-dev-harmony-fb",
+                "object-assign": "2.1.1",
+                "source-map": "0.4.4"
             },
             "dependencies": {
                 "esprima-fb": {
@@ -7736,7 +7735,7 @@
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
                     "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
                     "requires": {
-                        "amdefine": ">=0.0.4"
+                        "amdefine": "1.0.1"
                     }
                 }
             }
@@ -7746,8 +7745,8 @@
             "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
             "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
             "requires": {
-                "is-promise": "^2.0.0",
-                "promise": "^7.0.1"
+                "is-promise": "2.1.0",
+                "promise": "7.3.1"
             }
         },
         "jsx-to-string": {
@@ -7755,9 +7754,9 @@
             "resolved": "https://registry.npmjs.org/jsx-to-string/-/jsx-to-string-1.4.0.tgz",
             "integrity": "sha1-Ztw013PaufQP6ZPP+ZQOXaZVtwU=",
             "requires": {
-                "immutable": "^4.0.0-rc.9",
-                "json-stringify-pretty-compact": "^1.0.1",
-                "react": "^0.14.0"
+                "immutable": "4.0.0-rc.12",
+                "json-stringify-pretty-compact": "1.2.0",
+                "react": "0.14.9"
             },
             "dependencies": {
                 "fbjs": {
@@ -7765,11 +7764,11 @@
                     "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz",
                     "integrity": "sha1-lja3cF9bqWhNRLcveDISVK/IYPc=",
                     "requires": {
-                        "core-js": "^1.0.0",
-                        "loose-envify": "^1.0.0",
-                        "promise": "^7.0.3",
-                        "ua-parser-js": "^0.7.9",
-                        "whatwg-fetch": "^0.9.0"
+                        "core-js": "1.2.7",
+                        "loose-envify": "1.4.0",
+                        "promise": "7.3.1",
+                        "ua-parser-js": "0.7.20",
+                        "whatwg-fetch": "0.9.0"
                     }
                 },
                 "react": {
@@ -7777,8 +7776,8 @@
                     "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz",
                     "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=",
                     "requires": {
-                        "envify": "^3.0.0",
-                        "fbjs": "^0.6.1"
+                        "envify": "3.4.1",
+                        "fbjs": "0.6.1"
                     }
                 },
                 "whatwg-fetch": {
@@ -7795,7 +7794,7 @@
             "requires": {
                 "buffer-equal-constant-time": "1.0.1",
                 "ecdsa-sig-formatter": "1.0.11",
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "jws": {
@@ -7803,8 +7802,8 @@
             "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
             "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
             "requires": {
-                "jwa": "^1.4.1",
-                "safe-buffer": "^5.0.1"
+                "jwa": "1.4.1",
+                "safe-buffer": "5.1.2"
             }
         },
         "kareem": {
@@ -7827,8 +7826,8 @@
             "resolved": "https://registry.npmjs.org/kill-port/-/kill-port-1.6.0.tgz",
             "integrity": "sha512-gwHRBZ3OLBcupsOJZlIt2Xvf6QqFH3lfdpGnmonXJnJrqq819UXtItGEU1rCMXHK6sXFlxdpkw8ka56rtWw/eQ==",
             "requires": {
-                "get-them-args": "^1.3.1",
-                "shell-exec": "^1.0.2"
+                "get-them-args": "1.3.2",
+                "shell-exec": "1.0.2"
             }
         },
         "killable": {
@@ -7847,7 +7846,7 @@
             "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
             "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
             "requires": {
-                "graceful-fs": "^4.1.9"
+                "graceful-fs": "4.2.0"
             }
         },
         "latest-version": {
@@ -7855,7 +7854,7 @@
             "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
             "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
             "requires": {
-                "package-json": "^4.0.0"
+                "package-json": "4.0.1"
             }
         },
         "lazy-cache": {
@@ -7868,7 +7867,7 @@
             "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
             "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
             "requires": {
-                "readable-stream": "^2.0.5"
+                "readable-stream": "2.3.6"
             }
         },
         "lcid": {
@@ -7876,7 +7875,7 @@
             "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
             "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
             "requires": {
-                "invert-kv": "^1.0.0"
+                "invert-kv": "1.0.0"
             }
         },
         "levn": {
@@ -7885,8 +7884,8 @@
             "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
             "dev": true,
             "requires": {
-                "prelude-ls": "~1.1.2",
-                "type-check": "~0.3.2"
+                "prelude-ls": "1.1.2",
+                "type-check": "0.3.2"
             }
         },
         "lines-and-columns": {
@@ -7899,11 +7898,11 @@
             "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
             "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "parse-json": "^2.2.0",
-                "pify": "^2.0.0",
-                "pinkie-promise": "^2.0.0",
-                "strip-bom": "^2.0.0"
+                "graceful-fs": "4.2.0",
+                "parse-json": "2.2.0",
+                "pify": "2.3.0",
+                "pinkie-promise": "2.0.1",
+                "strip-bom": "2.0.0"
             },
             "dependencies": {
                 "parse-json": {
@@ -7911,7 +7910,7 @@
                     "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
                     "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
                     "requires": {
-                        "error-ex": "^1.2.0"
+                        "error-ex": "1.3.2"
                     }
                 }
             }
@@ -7927,9 +7926,9 @@
             "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
             "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
             "requires": {
-                "big.js": "^5.2.2",
-                "emojis-list": "^2.0.0",
-                "json5": "^1.0.1"
+                "big.js": "5.2.2",
+                "emojis-list": "2.1.0",
+                "json5": "1.0.1"
             }
         },
         "locate-path": {
@@ -7937,8 +7936,8 @@
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
             "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
             "requires": {
-                "p-locate": "^2.0.0",
-                "path-exists": "^3.0.0"
+                "p-locate": "2.0.0",
+                "path-exists": "3.0.0"
             }
         },
         "lodash": {
@@ -8038,7 +8037,7 @@
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
             "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
             "requires": {
-                "chalk": "^2.0.1"
+                "chalk": "2.4.2"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -8046,7 +8045,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -8054,9 +8053,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -8064,7 +8063,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -8081,8 +8080,8 @@
             "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==",
             "dev": true,
             "requires": {
-                "es6-symbol": "^3.1.1",
-                "object.assign": "^4.1.0"
+                "es6-symbol": "3.1.1",
+                "object.assign": "4.1.0"
             }
         },
         "longest": {
@@ -8095,7 +8094,7 @@
             "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
             "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
             "requires": {
-                "js-tokens": "^3.0.0 || ^4.0.0"
+                "js-tokens": "4.0.0"
             }
         },
         "loud-rejection": {
@@ -8103,8 +8102,8 @@
             "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
             "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
             "requires": {
-                "currently-unhandled": "^0.4.1",
-                "signal-exit": "^3.0.0"
+                "currently-unhandled": "0.4.1",
+                "signal-exit": "3.0.2"
             }
         },
         "lowercase-keys": {
@@ -8117,8 +8116,8 @@
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
             "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
             "requires": {
-                "pseudomap": "^1.0.2",
-                "yallist": "^2.1.2"
+                "pseudomap": "1.0.2",
+                "yallist": "2.1.2"
             },
             "dependencies": {
                 "yallist": {
@@ -8134,7 +8133,7 @@
             "integrity": "sha512-x/eBenweAHF+DsYy172sK4doRxZl0yrJnfxhLJiN7H6hPM3Ya0PfI6uBZshZ3ScFFSQD7HXgBqMdbnXKEZsO1g==",
             "requires": {
                 "cliss": "0.0.2",
-                "find-up": "^2.1.0",
+                "find-up": "2.1.0",
                 "for-each-property": "0.0.4",
                 "inspect-property": "0.0.6"
             }
@@ -8144,7 +8143,7 @@
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
             "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
             "requires": {
-                "pify": "^3.0.0"
+                "pify": "3.0.0"
             },
             "dependencies": {
                 "pify": {
@@ -8172,7 +8171,7 @@
             "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
             "dev": true,
             "requires": {
-                "p-defer": "^1.0.0"
+                "p-defer": "1.0.0"
             }
         },
         "map-cache": {
@@ -8190,7 +8189,7 @@
             "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
             "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
             "requires": {
-                "object-visit": "^1.0.0"
+                "object-visit": "1.0.1"
             }
         },
         "material-colors": {
@@ -8203,9 +8202,9 @@
             "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
             "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
             "requires": {
-                "hash-base": "^3.0.0",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "hash-base": "3.0.4",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "media-typer": {
@@ -8219,9 +8218,9 @@
             "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
             "dev": true,
             "requires": {
-                "map-age-cleaner": "^0.1.1",
-                "mimic-fn": "^2.0.0",
-                "p-is-promise": "^2.0.0"
+                "map-age-cleaner": "0.1.3",
+                "mimic-fn": "2.1.0",
+                "p-is-promise": "2.1.0"
             }
         },
         "memory-fs": {
@@ -8230,8 +8229,8 @@
             "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
             "dev": true,
             "requires": {
-                "errno": "^0.1.3",
-                "readable-stream": "^2.0.1"
+                "errno": "0.1.7",
+                "readable-stream": "2.3.6"
             }
         },
         "memory-pager": {
@@ -8245,16 +8244,16 @@
             "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
             "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
             "requires": {
-                "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"
+                "camelcase-keys": "2.1.0",
+                "decamelize": "1.2.0",
+                "loud-rejection": "1.6.0",
+                "map-obj": "1.0.1",
+                "minimist": "1.2.0",
+                "normalize-package-data": "2.5.0",
+                "object-assign": "4.1.1",
+                "read-pkg-up": "1.0.1",
+                "redent": "1.0.0",
+                "trim-newlines": "1.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -8285,19 +8284,19 @@
             "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
             "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
             "requires": {
-                "arr-diff": "^4.0.0",
-                "array-unique": "^0.3.2",
-                "braces": "^2.3.1",
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "extglob": "^2.0.4",
-                "fragment-cache": "^0.2.1",
-                "kind-of": "^6.0.2",
-                "nanomatch": "^1.2.9",
-                "object.pick": "^1.3.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.2"
+                "arr-diff": "4.0.0",
+                "array-unique": "0.3.2",
+                "braces": "2.3.2",
+                "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.13",
+                "object.pick": "1.3.0",
+                "regex-not": "1.0.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             }
         },
         "miller-rabin": {
@@ -8305,8 +8304,8 @@
             "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
             "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
             "requires": {
-                "bn.js": "^4.0.0",
-                "brorand": "^1.0.1"
+                "bn.js": "4.11.8",
+                "brorand": "1.1.0"
             }
         },
         "mime": {
@@ -8353,7 +8352,7 @@
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
             "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
             "requires": {
-                "brace-expansion": "^1.1.7"
+                "brace-expansion": "1.1.11"
             }
         },
         "minimist": {
@@ -8366,8 +8365,8 @@
             "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
             "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
             "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
+                "safe-buffer": "5.1.2",
+                "yallist": "3.0.3"
             }
         },
         "minizlib": {
@@ -8375,7 +8374,7 @@
             "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
             "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
             "requires": {
-                "minipass": "^2.2.1"
+                "minipass": "2.3.5"
             }
         },
         "mississippi": {
@@ -8384,16 +8383,16 @@
             "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
             "dev": true,
             "requires": {
-                "concat-stream": "^1.5.0",
-                "duplexify": "^3.4.2",
-                "end-of-stream": "^1.1.0",
-                "flush-write-stream": "^1.0.0",
-                "from2": "^2.1.0",
-                "parallel-transform": "^1.1.0",
-                "pump": "^2.0.1",
-                "pumpify": "^1.3.3",
-                "stream-each": "^1.1.0",
-                "through2": "^2.0.0"
+                "concat-stream": "1.6.2",
+                "duplexify": "3.7.1",
+                "end-of-stream": "1.4.1",
+                "flush-write-stream": "1.1.1",
+                "from2": "2.3.0",
+                "parallel-transform": "1.1.0",
+                "pump": "2.0.1",
+                "pumpify": "1.5.1",
+                "stream-each": "1.2.3",
+                "through2": "2.0.5"
             }
         },
         "mixin-deep": {
@@ -8401,8 +8400,8 @@
             "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
             "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
             "requires": {
-                "for-in": "^1.0.2",
-                "is-extendable": "^1.0.1"
+                "for-in": "1.0.2",
+                "is-extendable": "1.0.1"
             },
             "dependencies": {
                 "is-extendable": {
@@ -8410,7 +8409,7 @@
                     "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
                     "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
                     "requires": {
-                        "is-plain-object": "^2.0.4"
+                        "is-plain-object": "2.0.4"
                     }
                 }
             }
@@ -8421,8 +8420,8 @@
             "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
             "dev": true,
             "requires": {
-                "for-in": "^0.1.3",
-                "is-extendable": "^0.1.1"
+                "for-in": "0.1.8",
+                "is-extendable": "0.1.1"
             },
             "dependencies": {
                 "for-in": {
@@ -8456,8 +8455,8 @@
             "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz",
             "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==",
             "requires": {
-                "hoist-non-react-statics": "^3.0.0",
-                "react-lifecycles-compat": "^3.0.2"
+                "hoist-non-react-statics": "3.3.0",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "mobx-react-devtools": {
@@ -8516,12 +8515,12 @@
                     "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
                     "dev": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "supports-color": {
@@ -8530,7 +8529,7 @@
                     "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -8546,7 +8545,7 @@
             "integrity": "sha512-2YdWrdf1PJgxcCrT1tWoL6nHuk6hCxhddAAaEh8QJL231ci4+P9FLyqopbTm2Z2sAU6mhCri+wd9r1hOcHdoMw==",
             "requires": {
                 "mongodb-core": "3.2.7",
-                "safe-buffer": "^5.1.2"
+                "safe-buffer": "5.1.2"
             },
             "dependencies": {
                 "bson": {
@@ -8559,10 +8558,10 @@
                     "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz",
                     "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==",
                     "requires": {
-                        "bson": "^1.1.1",
-                        "require_optional": "^1.0.1",
-                        "safe-buffer": "^5.1.2",
-                        "saslprep": "^1.0.0"
+                        "bson": "1.1.1",
+                        "require_optional": "1.0.1",
+                        "safe-buffer": "5.1.2",
+                        "saslprep": "1.0.3"
                     }
                 }
             }
@@ -8572,8 +8571,8 @@
             "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz",
             "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==",
             "requires": {
-                "bson": "~1.0.4",
-                "require_optional": "~1.0.0"
+                "bson": "1.0.9",
+                "require_optional": "1.0.1"
             }
         },
         "mongoose": {
@@ -8582,7 +8581,7 @@
             "integrity": "sha512-5uecJSyl2TwbGM9vJteP4C54zsQL6qllq1qe/JPGO3oqIWcK/PnzCL91E0gfPH5VVpvWGX+6PafNYmU3NK8S7w==",
             "requires": {
                 "async": "2.6.2",
-                "bson": "~1.1.1",
+                "bson": "1.1.1",
                 "kareem": "2.3.0",
                 "mongodb": "3.2.7",
                 "mongodb-core": "3.2.7",
@@ -8601,7 +8600,7 @@
                     "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
                     "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
                     "requires": {
-                        "lodash": "^4.17.11"
+                        "lodash": "4.17.15"
                     }
                 },
                 "bson": {
@@ -8614,10 +8613,10 @@
                     "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz",
                     "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==",
                     "requires": {
-                        "bson": "^1.1.1",
-                        "require_optional": "^1.0.1",
-                        "safe-buffer": "^5.1.2",
-                        "saslprep": "^1.0.0"
+                        "bson": "1.1.1",
+                        "require_optional": "1.0.1",
+                        "safe-buffer": "5.1.2",
+                        "saslprep": "1.0.3"
                     }
                 },
                 "ms": {
@@ -8638,12 +8637,12 @@
             "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1",
-                "copy-concurrently": "^1.0.0",
-                "fs-write-stream-atomic": "^1.0.8",
-                "mkdirp": "^0.5.1",
-                "rimraf": "^2.5.4",
-                "run-queue": "^1.0.3"
+                "aproba": "1.2.0",
+                "copy-concurrently": "1.0.5",
+                "fs-write-stream-atomic": "1.0.10",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1",
+                "run-queue": "1.0.3"
             },
             "dependencies": {
                 "rimraf": {
@@ -8652,7 +8651,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -8669,7 +8668,7 @@
             "requires": {
                 "bluebird": "3.5.1",
                 "debug": "3.1.0",
-                "regexp-clone": "^1.0.0",
+                "regexp-clone": "1.0.0",
                 "safe-buffer": "5.1.2",
                 "sliced": "1.0.1"
             },
@@ -8700,8 +8699,8 @@
             "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
             "dev": true,
             "requires": {
-                "dns-packet": "^1.3.1",
-                "thunky": "^1.0.2"
+                "dns-packet": "1.3.1",
+                "thunky": "1.0.3"
             }
         },
         "multicast-dns-service-types": {
@@ -8720,17 +8719,17 @@
             "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
             "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
             "requires": {
-                "arr-diff": "^4.0.0",
-                "array-unique": "^0.3.2",
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "fragment-cache": "^0.2.1",
-                "is-windows": "^1.0.2",
-                "kind-of": "^6.0.2",
-                "object.pick": "^1.3.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "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.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             }
         },
         "napi-build-utils": {
@@ -8748,9 +8747,9 @@
             "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz",
             "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==",
             "requires": {
-                "debug": "^3.2.6",
-                "iconv-lite": "^0.4.4",
-                "sax": "^1.2.4"
+                "debug": "3.2.6",
+                "iconv-lite": "0.4.24",
+                "sax": "1.2.4"
             },
             "dependencies": {
                 "debug": {
@@ -8758,7 +8757,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -8795,7 +8794,7 @@
             "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.9.0.tgz",
             "integrity": "sha512-jmEOvv0eanWjhX8dX1pmjb7oJl1U1oR4FOh0b2GnvALwSYoOdU7sj+kLDSAyjo4pfC9aj/IxkloxdLJQhSSQBA==",
             "requires": {
-                "semver": "^5.4.1"
+                "semver": "5.7.0"
             }
         },
         "node-ensure": {
@@ -8808,8 +8807,8 @@
             "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
             "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==",
             "requires": {
-                "object.getownpropertydescriptors": "^2.0.3",
-                "semver": "^5.7.0"
+                "object.getownpropertydescriptors": "2.0.3",
+                "semver": "5.7.0"
             }
         },
         "node-fetch": {
@@ -8817,8 +8816,8 @@
             "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
             "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
             "requires": {
-                "encoding": "^0.1.11",
-                "is-stream": "^1.0.1"
+                "encoding": "0.1.12",
+                "is-stream": "1.1.0"
             }
         },
         "node-forge": {
@@ -8832,18 +8831,18 @@
             "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
             "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
             "requires": {
-                "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"
+                "fstream": "1.0.12",
+                "glob": "7.1.4",
+                "graceful-fs": "4.2.0",
+                "mkdirp": "0.5.1",
+                "nopt": "3.0.6",
+                "npmlog": "4.1.2",
+                "osenv": "0.1.5",
+                "request": "2.88.0",
+                "rimraf": "2.7.1",
+                "semver": "5.3.0",
+                "tar": "2.2.2",
+                "which": "1.3.1"
             },
             "dependencies": {
                 "assert-plus": {
@@ -8866,9 +8865,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -8876,8 +8875,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -8885,9 +8884,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "nopt": {
@@ -8895,7 +8894,7 @@
                     "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
                     "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
                     "requires": {
-                        "abbrev": "1"
+                        "abbrev": "1.1.1"
                     }
                 },
                 "oauth-sign": {
@@ -8913,26 +8912,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     }
                 },
                 "rimraf": {
@@ -8940,7 +8939,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "semver": {
@@ -8953,9 +8952,9 @@
                     "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
                     "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
                     "requires": {
-                        "block-stream": "*",
-                        "fstream": "^1.0.12",
-                        "inherits": "2"
+                        "block-stream": "0.0.9",
+                        "fstream": "1.0.12",
+                        "inherits": "2.0.3"
                     }
                 }
             }
@@ -8966,29 +8965,29 @@
             "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
             "dev": true,
             "requires": {
-                "assert": "^1.1.1",
-                "browserify-zlib": "^0.2.0",
-                "buffer": "^4.3.0",
-                "console-browserify": "^1.1.0",
-                "constants-browserify": "^1.0.0",
-                "crypto-browserify": "^3.11.0",
-                "domain-browser": "^1.1.1",
-                "events": "^3.0.0",
-                "https-browserify": "^1.0.0",
-                "os-browserify": "^0.3.0",
+                "assert": "1.5.0",
+                "browserify-zlib": "0.2.0",
+                "buffer": "4.9.1",
+                "console-browserify": "1.1.0",
+                "constants-browserify": "1.0.0",
+                "crypto-browserify": "3.12.0",
+                "domain-browser": "1.2.0",
+                "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",
+                "process": "0.11.10",
+                "punycode": "1.4.1",
+                "querystring-es3": "0.2.1",
+                "readable-stream": "2.3.6",
+                "stream-browserify": "2.0.2",
+                "stream-http": "2.8.3",
+                "string_decoder": "1.1.1",
+                "timers-browserify": "2.0.10",
                 "tty-browserify": "0.0.0",
-                "url": "^0.11.0",
-                "util": "^0.11.0",
-                "vm-browserify": "^1.0.1"
+                "url": "0.11.0",
+                "util": "0.11.1",
+                "vm-browserify": "1.1.0"
             },
             "dependencies": {
                 "punycode": {
@@ -9005,11 +9004,11 @@
             "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==",
             "dev": true,
             "requires": {
-                "growly": "^1.3.0",
-                "is-wsl": "^1.1.0",
-                "semver": "^5.5.0",
-                "shellwords": "^0.1.1",
-                "which": "^1.3.0"
+                "growly": "1.3.0",
+                "is-wsl": "1.1.0",
+                "semver": "5.7.0",
+                "shellwords": "0.1.1",
+                "which": "1.3.1"
             }
         },
         "node-pre-gyp": {
@@ -9017,16 +9016,16 @@
             "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
             "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
             "requires": {
-                "detect-libc": "^1.0.2",
-                "mkdirp": "^0.5.1",
-                "needle": "^2.2.1",
-                "nopt": "^4.0.1",
-                "npm-packlist": "^1.1.6",
-                "npmlog": "^4.0.2",
-                "rc": "^1.2.7",
-                "rimraf": "^2.6.1",
-                "semver": "^5.3.0",
-                "tar": "^4"
+                "detect-libc": "1.0.3",
+                "mkdirp": "0.5.1",
+                "needle": "2.4.0",
+                "nopt": "4.0.1",
+                "npm-packlist": "1.4.4",
+                "npmlog": "4.1.2",
+                "rc": "1.2.8",
+                "rimraf": "2.7.1",
+                "semver": "5.7.0",
+                "tar": "4.4.10"
             },
             "dependencies": {
                 "rimraf": {
@@ -9034,7 +9033,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -9044,23 +9043,23 @@
             "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
             "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
             "requires": {
-                "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.11",
-                "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.4",
-                "stdout-stream": "^1.4.0",
-                "true-case-path": "^1.0.2"
+                "async-foreach": "0.1.3",
+                "chalk": "1.1.3",
+                "cross-spawn": "3.0.1",
+                "gaze": "1.1.3",
+                "get-stdin": "4.0.1",
+                "glob": "7.1.4",
+                "in-publish": "2.0.0",
+                "lodash": "4.17.15",
+                "meow": "3.7.0",
+                "mkdirp": "0.5.1",
+                "nan": "2.14.0",
+                "node-gyp": "3.8.0",
+                "npmlog": "4.1.2",
+                "request": "2.88.0",
+                "sass-graph": "2.2.4",
+                "stdout-stream": "1.4.1",
+                "true-case-path": "1.0.3"
             },
             "dependencies": {
                 "assert-plus": {
@@ -9083,9 +9082,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "get-stdin": {
@@ -9098,8 +9097,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -9107,9 +9106,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -9127,26 +9126,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     }
                 }
             }
@@ -9161,16 +9160,16 @@
             "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz",
             "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==",
             "requires": {
-                "chokidar": "^2.1.5",
-                "debug": "^3.1.0",
-                "ignore-by-default": "^1.0.1",
-                "minimatch": "^3.0.4",
-                "pstree.remy": "^1.1.6",
-                "semver": "^5.5.0",
-                "supports-color": "^5.2.0",
-                "touch": "^3.1.0",
-                "undefsafe": "^2.0.2",
-                "update-notifier": "^2.5.0"
+                "chokidar": "2.1.6",
+                "debug": "3.2.6",
+                "ignore-by-default": "1.0.1",
+                "minimatch": "3.0.4",
+                "pstree.remy": "1.1.7",
+                "semver": "5.7.0",
+                "supports-color": "5.5.0",
+                "touch": "3.1.0",
+                "undefsafe": "2.0.2",
+                "update-notifier": "2.5.0"
             },
             "dependencies": {
                 "debug": {
@@ -9178,7 +9177,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -9191,7 +9190,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -9206,8 +9205,8 @@
             "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
             "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
             "requires": {
-                "abbrev": "1",
-                "osenv": "^0.1.4"
+                "abbrev": "1.1.1",
+                "osenv": "0.1.5"
             }
         },
         "normalize-package-data": {
@@ -9215,10 +9214,10 @@
             "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
             "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
             "requires": {
-                "hosted-git-info": "^2.1.4",
-                "resolve": "^1.10.0",
-                "semver": "2 || 3 || 4 || 5",
-                "validate-npm-package-license": "^3.0.1"
+                "hosted-git-info": "2.7.1",
+                "resolve": "1.11.1",
+                "semver": "5.7.0",
+                "validate-npm-package-license": "3.0.4"
             }
         },
         "normalize-path": {
@@ -9232,141 +9231,141 @@
             "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
         },
         "npm": {
-            "version": "6.13.4",
-            "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.4.tgz",
-            "integrity": "sha512-vTcUL4SCg3AzwInWTbqg1OIaOXlzKSS8Mb8kc5avwrJpcvevDA5J9BhYSuei+fNs3pwOp4lzA5x2FVDXACvoXA==",
-            "requires": {
-                "JSONStream": "^1.3.5",
-                "abbrev": "~1.1.1",
-                "ansicolors": "~0.3.2",
-                "ansistyles": "~0.1.3",
-                "aproba": "^2.0.0",
-                "archy": "~1.0.0",
-                "bin-links": "^1.1.6",
-                "bluebird": "^3.5.5",
-                "byte-size": "^5.0.1",
-                "cacache": "^12.0.3",
-                "call-limit": "^1.1.1",
-                "chownr": "^1.1.3",
-                "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.4",
-                "graceful-fs": "^4.2.3",
-                "has-unicode": "~2.0.1",
-                "hosted-git-info": "^2.8.5",
-                "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",
-                "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.0",
-                "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.1",
-                "move-concurrently": "^1.0.1",
-                "node-gyp": "^5.0.5",
-                "nopt": "~4.0.1",
-                "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.7",
-                "npm-pick-manifest": "^3.0.2",
-                "npm-profile": "^4.0.2",
-                "npm-registry-fetch": "^4.0.2",
-                "npm-user-validate": "~1.0.0",
-                "npmlog": "~4.1.2",
-                "once": "~1.4.0",
-                "opener": "^1.5.1",
-                "osenv": "^0.1.5",
-                "pacote": "^9.5.11",
-                "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.4.0",
-                "readdir-scoped-modules": "^1.1.0",
-                "request": "^2.88.0",
-                "retry": "^0.12.0",
-                "rimraf": "^2.6.3",
-                "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",
+            "version": "6.13.6",
+            "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.6.tgz",
+            "integrity": "sha512-NomC08kv7HIl1FOyLOe9Hp89kYsOsvx52huVIJ7i8hFW8Xp65lDwe/8wTIrh9q9SaQhA8hTrfXPh3BEL3TmMpw==",
+            "requires": {
+                "JSONStream": "1.3.5",
+                "abbrev": "1.1.1",
+                "ansicolors": "0.3.2",
+                "ansistyles": "0.1.3",
+                "aproba": "2.0.0",
+                "archy": "1.0.0",
+                "bin-links": "1.1.6",
+                "bluebird": "3.5.5",
+                "byte-size": "5.0.1",
+                "cacache": "12.0.3",
+                "call-limit": "1.1.1",
+                "chownr": "1.1.3",
+                "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": "1.0.1",
+                "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.4",
+                "graceful-fs": "4.2.3",
+                "has-unicode": "2.0.1",
+                "hosted-git-info": "2.8.5",
+                "iferr": "1.0.2",
+                "imurmurhash": "0.1.4",
+                "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",
+                "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.0",
+                "lock-verify": "2.1.0",
+                "lockfile": "1.0.4",
+                "lodash._baseindexof": "3.1.0",
+                "lodash._baseuniq": "4.6.0",
+                "lodash._bindcallback": "3.0.1",
+                "lodash._cacheindexof": "3.0.2",
+                "lodash._createcache": "3.1.2",
+                "lodash._getnative": "3.9.1",
+                "lodash.clonedeep": "4.5.0",
+                "lodash.restparam": "3.6.1",
+                "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.1",
+                "move-concurrently": "1.0.1",
+                "node-gyp": "5.0.5",
+                "nopt": "4.0.1",
+                "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.7",
+                "npm-pick-manifest": "3.0.2",
+                "npm-profile": "4.0.2",
+                "npm-registry-fetch": "4.0.2",
+                "npm-user-validate": "1.0.0",
+                "npmlog": "4.1.2",
+                "once": "1.4.0",
+                "opener": "1.5.1",
+                "osenv": "0.1.5",
+                "pacote": "9.5.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.4.0",
+                "readdir-scoped-modules": "1.1.0",
+                "request": "2.88.0",
+                "retry": "0.12.0",
+                "rimraf": "2.6.3",
+                "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"
+                "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"
             },
             "dependencies": {
                 "JSONStream": {
                     "version": "1.3.5",
                     "bundled": true,
                     "requires": {
-                        "jsonparse": "^1.2.0",
-                        "through": ">=2.2.7 <3"
+                        "jsonparse": "1.3.1",
+                        "through": "2.3.8"
                     }
                 },
                 "abbrev": {
@@ -9377,31 +9376,31 @@
                     "version": "4.3.0",
                     "bundled": true,
                     "requires": {
-                        "es6-promisify": "^5.0.0"
+                        "es6-promisify": "5.0.0"
                     }
                 },
                 "agentkeepalive": {
                     "version": "3.5.2",
                     "bundled": true,
                     "requires": {
-                        "humanize-ms": "^1.2.1"
+                        "humanize-ms": "1.2.1"
                     }
                 },
                 "ajv": {
                     "version": "5.5.2",
                     "bundled": true,
                     "requires": {
-                        "co": "^4.6.0",
-                        "fast-deep-equal": "^1.0.0",
-                        "fast-json-stable-stringify": "^2.0.0",
-                        "json-schema-traverse": "^0.3.0"
+                        "co": "4.6.0",
+                        "fast-deep-equal": "1.1.0",
+                        "fast-json-stable-stringify": "2.0.0",
+                        "json-schema-traverse": "0.3.1"
                     }
                 },
                 "ansi-align": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.0.0"
+                        "string-width": "2.1.1"
                     }
                 },
                 "ansi-regex": {
@@ -9412,7 +9411,7 @@
                     "version": "3.2.1",
                     "bundled": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.1"
                     }
                 },
                 "ansicolors": {
@@ -9435,28 +9434,28 @@
                     "version": "1.1.4",
                     "bundled": true,
                     "requires": {
-                        "delegates": "^1.0.0",
-                        "readable-stream": "^2.0.6"
+                        "delegates": "1.0.0",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9469,7 +9468,7 @@
                     "version": "0.2.4",
                     "bundled": true,
                     "requires": {
-                        "safer-buffer": "~2.1.0"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "assert-plus": {
@@ -9497,19 +9496,19 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "tweetnacl": "^0.14.3"
+                        "tweetnacl": "0.14.5"
                     }
                 },
                 "bin-links": {
                     "version": "1.1.6",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "cmd-shim": "3.0.3",
+                        "gentle-fs": "2.3.0",
+                        "graceful-fs": "4.2.3",
+                        "npm-normalize-package-bin": "1.0.1",
+                        "write-file-atomic": "2.4.3"
                     }
                 },
                 "bluebird": {
@@ -9520,20 +9519,20 @@
                     "version": "1.3.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "ansi-align": "2.0.0",
+                        "camelcase": "4.1.0",
+                        "chalk": "2.4.1",
+                        "cli-boxes": "1.0.0",
+                        "string-width": "2.1.1",
+                        "term-size": "1.2.0",
+                        "widest-line": "2.0.0"
                     }
                 },
                 "brace-expansion": {
                     "version": "1.1.11",
                     "bundled": true,
                     "requires": {
-                        "balanced-match": "^1.0.0",
+                        "balanced-match": "1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
@@ -9557,21 +9556,21 @@
                     "version": "12.0.3",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "chownr": "1.1.3",
+                        "figgy-pudding": "3.5.1",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "infer-owner": "1.0.4",
+                        "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"
                     }
                 },
                 "call-limit": {
@@ -9594,9 +9593,9 @@
                     "version": "2.4.1",
                     "bundled": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.4.0"
                     }
                 },
                 "chownr": {
@@ -9611,7 +9610,7 @@
                     "version": "2.0.10",
                     "bundled": true,
                     "requires": {
-                        "ip-regex": "^2.1.0"
+                        "ip-regex": "2.1.0"
                     }
                 },
                 "cli-boxes": {
@@ -9622,26 +9621,26 @@
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.0.0",
-                        "strip-ansi": "^3.0.1"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "3.0.1"
                     }
                 },
                 "cli-table3": {
                     "version": "0.5.1",
                     "bundled": true,
                     "requires": {
-                        "colors": "^1.1.2",
-                        "object-assign": "^4.1.0",
-                        "string-width": "^2.1.1"
+                        "colors": "1.3.3",
+                        "object-assign": "4.1.1",
+                        "string-width": "2.1.1"
                     }
                 },
                 "cliui": {
                     "version": "4.1.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.1.1",
-                        "strip-ansi": "^4.0.0",
-                        "wrap-ansi": "^2.0.0"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "4.0.0",
+                        "wrap-ansi": "2.1.0"
                     },
                     "dependencies": {
                         "ansi-regex": {
@@ -9652,7 +9651,7 @@
                             "version": "4.0.0",
                             "bundled": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -9665,8 +9664,8 @@
                     "version": "3.0.3",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "mkdirp": "~0.5.0"
+                        "graceful-fs": "4.2.3",
+                        "mkdirp": "0.5.1"
                     }
                 },
                 "co": {
@@ -9681,7 +9680,7 @@
                     "version": "1.9.1",
                     "bundled": true,
                     "requires": {
-                        "color-name": "^1.1.1"
+                        "color-name": "1.1.3"
                     }
                 },
                 "color-name": {
@@ -9697,15 +9696,15 @@
                     "version": "1.5.4",
                     "bundled": true,
                     "requires": {
-                        "strip-ansi": "^3.0.0",
-                        "wcwidth": "^1.0.0"
+                        "strip-ansi": "3.0.1",
+                        "wcwidth": "1.0.1"
                     }
                 },
                 "combined-stream": {
                     "version": "1.0.6",
                     "bundled": true,
                     "requires": {
-                        "delayed-stream": "~1.0.0"
+                        "delayed-stream": "1.0.0"
                     }
                 },
                 "concat-map": {
@@ -9716,30 +9715,30 @@
                     "version": "1.6.2",
                     "bundled": true,
                     "requires": {
-                        "buffer-from": "^1.0.0",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^2.2.2",
-                        "typedarray": "^0.0.6"
+                        "buffer-from": "1.0.0",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6",
+                        "typedarray": "0.0.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9748,20 +9747,20 @@
                     "version": "1.1.12",
                     "bundled": true,
                     "requires": {
-                        "ini": "^1.3.4",
-                        "proto-list": "~1.2.1"
+                        "ini": "1.3.5",
+                        "proto-list": "1.2.4"
                     }
                 },
                 "configstore": {
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "dot-prop": "4.2.0",
+                        "graceful-fs": "4.2.3",
+                        "make-dir": "1.3.0",
+                        "unique-string": "1.0.0",
+                        "write-file-atomic": "2.4.3",
+                        "xdg-basedir": "3.0.0"
                     }
                 },
                 "console-control-strings": {
@@ -9772,12 +9771,12 @@
                     "version": "1.0.5",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1",
-                        "fs-write-stream-atomic": "^1.0.8",
-                        "iferr": "^0.1.5",
-                        "mkdirp": "^0.5.1",
-                        "rimraf": "^2.5.4",
-                        "run-queue": "^1.0.0"
+                        "aproba": "1.2.0",
+                        "fs-write-stream-atomic": "1.0.10",
+                        "iferr": "0.1.5",
+                        "mkdirp": "0.5.1",
+                        "rimraf": "2.6.3",
+                        "run-queue": "1.0.3"
                     },
                     "dependencies": {
                         "aproba": {
@@ -9798,24 +9797,24 @@
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "capture-stack-trace": "^1.0.0"
+                        "capture-stack-trace": "1.0.0"
                     }
                 },
                 "cross-spawn": {
                     "version": "5.1.0",
                     "bundled": true,
                     "requires": {
-                        "lru-cache": "^4.0.1",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "lru-cache": "4.1.5",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "lru-cache": {
                             "version": "4.1.5",
                             "bundled": true,
                             "requires": {
-                                "pseudomap": "^1.0.2",
-                                "yallist": "^2.1.2"
+                                "pseudomap": "1.0.2",
+                                "yallist": "2.1.2"
                             }
                         },
                         "yallist": {
@@ -9836,7 +9835,7 @@
                     "version": "1.14.1",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0"
+                        "assert-plus": "1.0.0"
                     }
                 },
                 "debug": {
@@ -9872,14 +9871,14 @@
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "clone": "^1.0.2"
+                        "clone": "1.0.4"
                     }
                 },
                 "define-properties": {
                     "version": "1.1.3",
                     "bundled": true,
                     "requires": {
-                        "object-keys": "^1.0.12"
+                        "object-keys": "1.0.12"
                     }
                 },
                 "delayed-stream": {
@@ -9902,15 +9901,15 @@
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "asap": "^2.0.0",
-                        "wrappy": "1"
+                        "asap": "2.0.6",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "dot-prop": {
                     "version": "4.2.0",
                     "bundled": true,
                     "requires": {
-                        "is-obj": "^1.0.0"
+                        "is-obj": "1.0.1"
                     }
                 },
                 "dotenv": {
@@ -9925,30 +9924,30 @@
                     "version": "3.6.0",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.0.0",
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.0",
-                        "stream-shift": "^1.0.0"
+                        "end-of-stream": "1.4.1",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6",
+                        "stream-shift": "1.0.0"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9958,8 +9957,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "jsbn": "~0.1.0",
-                        "safer-buffer": "^2.1.0"
+                        "jsbn": "0.1.1",
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "editor": {
@@ -9970,14 +9969,14 @@
                     "version": "0.1.12",
                     "bundled": true,
                     "requires": {
-                        "iconv-lite": "~0.4.13"
+                        "iconv-lite": "0.4.23"
                     }
                 },
                 "end-of-stream": {
                     "version": "1.4.1",
                     "bundled": true,
                     "requires": {
-                        "once": "^1.4.0"
+                        "once": "1.4.0"
                     }
                 },
                 "env-paths": {
@@ -9992,27 +9991,27 @@
                     "version": "0.1.7",
                     "bundled": true,
                     "requires": {
-                        "prr": "~1.0.1"
+                        "prr": "1.0.1"
                     }
                 },
                 "es-abstract": {
                     "version": "1.12.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "es-to-primitive": "1.2.0",
+                        "function-bind": "1.1.1",
+                        "has": "1.0.3",
+                        "is-callable": "1.1.4",
+                        "is-regex": "1.0.4"
                     }
                 },
                 "es-to-primitive": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "is-callable": "^1.1.4",
-                        "is-date-object": "^1.0.1",
-                        "is-symbol": "^1.0.2"
+                        "is-callable": "1.1.4",
+                        "is-date-object": "1.0.1",
+                        "is-symbol": "1.0.2"
                     }
                 },
                 "es6-promise": {
@@ -10023,7 +10022,7 @@
                     "version": "5.0.0",
                     "bundled": true,
                     "requires": {
-                        "es6-promise": "^4.0.3"
+                        "es6-promise": "4.2.8"
                     }
                 },
                 "escape-string-regexp": {
@@ -10034,13 +10033,13 @@
                     "version": "0.7.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "cross-spawn": "5.1.0",
+                        "get-stream": "3.0.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     },
                     "dependencies": {
                         "get-stream": {
@@ -10077,35 +10076,35 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "locate-path": "^2.0.0"
+                        "locate-path": "2.0.0"
                     }
                 },
                 "flush-write-stream": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.4"
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -10118,37 +10117,37 @@
                     "version": "2.3.2",
                     "bundled": true,
                     "requires": {
-                        "asynckit": "^0.4.0",
+                        "asynckit": "0.4.0",
                         "combined-stream": "1.0.6",
-                        "mime-types": "^2.1.12"
+                        "mime-types": "2.1.19"
                     }
                 },
                 "from2": {
                     "version": "2.3.0",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.0"
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -10157,15 +10156,15 @@
                     "version": "1.2.7",
                     "bundled": true,
                     "requires": {
-                        "minipass": "^2.6.0"
+                        "minipass": "2.9.0"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -10174,19 +10173,19 @@
                     "version": "1.2.10",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "path-is-inside": "^1.0.1",
-                        "rimraf": "^2.5.2"
+                        "graceful-fs": "4.2.3",
+                        "path-is-inside": "1.0.2",
+                        "rimraf": "2.6.3"
                     }
                 },
                 "fs-write-stream-atomic": {
                     "version": "1.0.10",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "iferr": "^0.1.5",
-                        "imurmurhash": "^0.1.4",
-                        "readable-stream": "1 || 2"
+                        "graceful-fs": "4.2.3",
+                        "iferr": "0.1.5",
+                        "imurmurhash": "0.1.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "iferr": {
@@ -10197,20 +10196,20 @@
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -10227,14 +10226,14 @@
                     "version": "2.7.4",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.0.3",
-                        "console-control-strings": "^1.0.0",
-                        "has-unicode": "^2.0.0",
-                        "object-assign": "^4.1.0",
-                        "signal-exit": "^3.0.0",
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1",
-                        "wide-align": "^1.1.0"
+                        "aproba": "1.2.0",
+                        "console-control-strings": "1.1.0",
+                        "has-unicode": "2.0.1",
+                        "object-assign": "4.1.1",
+                        "signal-exit": "3.0.2",
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1",
+                        "wide-align": "1.1.2"
                     },
                     "dependencies": {
                         "aproba": {
@@ -10245,9 +10244,9 @@
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -10260,17 +10259,17 @@
                     "version": "2.3.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "aproba": "1.2.0",
+                        "chownr": "1.1.3",
+                        "cmd-shim": "3.0.3",
+                        "fs-vacuum": "1.2.10",
+                        "graceful-fs": "4.2.3",
+                        "iferr": "0.1.5",
+                        "infer-owner": "1.0.4",
+                        "mkdirp": "0.5.1",
+                        "path-is-inside": "1.0.2",
+                        "read-cmd-shim": "1.0.5",
+                        "slide": "1.1.6"
                     },
                     "dependencies": {
                         "aproba": {
@@ -10291,50 +10290,50 @@
                     "version": "4.1.0",
                     "bundled": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "getpass": {
                     "version": "0.1.7",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0"
+                        "assert-plus": "1.0.0"
                     }
                 },
                 "glob": {
                     "version": "7.1.4",
                     "bundled": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.4",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "global-dirs": {
                     "version": "0.1.1",
                     "bundled": true,
                     "requires": {
-                        "ini": "^1.3.4"
+                        "ini": "1.3.5"
                     }
                 },
                 "got": {
                     "version": "6.7.1",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "create-error-class": "3.0.2",
+                        "duplexer3": "0.1.4",
+                        "get-stream": "3.0.0",
+                        "is-redirect": "1.0.0",
+                        "is-retry-allowed": "1.1.0",
+                        "is-stream": "1.1.0",
+                        "lowercase-keys": "1.0.1",
+                        "safe-buffer": "5.1.2",
+                        "timed-out": "4.0.1",
+                        "unzip-response": "2.0.1",
+                        "url-parse-lax": "1.0.0"
                     },
                     "dependencies": {
                         "get-stream": {
@@ -10355,15 +10354,15 @@
                     "version": "5.1.0",
                     "bundled": true,
                     "requires": {
-                        "ajv": "^5.3.0",
-                        "har-schema": "^2.0.0"
+                        "ajv": "5.5.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "has": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "function-bind": "^1.1.1"
+                        "function-bind": "1.1.1"
                     }
                 },
                 "has-flag": {
@@ -10390,7 +10389,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "4",
+                        "agent-base": "4.3.0",
                         "debug": "3.1.0"
                     }
                 },
@@ -10398,31 +10397,31 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.14.2"
                     }
                 },
                 "https-proxy-agent": {
                     "version": "2.2.4",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "^4.3.0",
-                        "debug": "^3.1.0"
+                        "agent-base": "4.3.0",
+                        "debug": "3.1.0"
                     }
                 },
                 "humanize-ms": {
                     "version": "1.2.1",
                     "bundled": true,
                     "requires": {
-                        "ms": "^2.0.0"
+                        "ms": "2.1.1"
                     }
                 },
                 "iconv-lite": {
                     "version": "0.4.23",
                     "bundled": true,
                     "requires": {
-                        "safer-buffer": ">= 2.1.2 < 3"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "iferr": {
@@ -10433,7 +10432,7 @@
                     "version": "3.0.3",
                     "bundled": true,
                     "requires": {
-                        "minimatch": "^3.0.4"
+                        "minimatch": "3.0.4"
                     }
                 },
                 "import-lazy": {
@@ -10452,8 +10451,8 @@
                     "version": "1.0.6",
                     "bundled": true,
                     "requires": {
-                        "once": "^1.3.0",
-                        "wrappy": "1"
+                        "once": "1.4.0",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "inherits": {
@@ -10468,14 +10467,14 @@
                     "version": "1.10.3",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "glob": "7.1.4",
+                        "npm-package-arg": "6.1.1",
+                        "promzard": "0.3.0",
+                        "read": "1.0.7",
+                        "read-package-json": "2.1.1",
+                        "semver": "5.7.1",
+                        "validate-npm-package-license": "3.0.4",
+                        "validate-npm-package-name": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -10498,7 +10497,7 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "ci-info": "^1.0.0"
+                        "ci-info": "1.6.0"
                     },
                     "dependencies": {
                         "ci-info": {
@@ -10511,7 +10510,7 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "cidr-regex": "^2.0.10"
+                        "cidr-regex": "2.0.10"
                     }
                 },
                 "is-date-object": {
@@ -10522,15 +10521,15 @@
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "number-is-nan": "^1.0.0"
+                        "number-is-nan": "1.0.1"
                     }
                 },
                 "is-installed-globally": {
                     "version": "0.1.0",
                     "bundled": true,
                     "requires": {
-                        "global-dirs": "^0.1.0",
-                        "is-path-inside": "^1.0.0"
+                        "global-dirs": "0.1.1",
+                        "is-path-inside": "1.0.1"
                     }
                 },
                 "is-npm": {
@@ -10545,7 +10544,7 @@
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "path-is-inside": "^1.0.1"
+                        "path-is-inside": "1.0.2"
                     }
                 },
                 "is-redirect": {
@@ -10556,7 +10555,7 @@
                     "version": "1.0.4",
                     "bundled": true,
                     "requires": {
-                        "has": "^1.0.1"
+                        "has": "1.0.3"
                     }
                 },
                 "is-retry-allowed": {
@@ -10571,7 +10570,7 @@
                     "version": "1.0.2",
                     "bundled": true,
                     "requires": {
-                        "has-symbols": "^1.0.0"
+                        "has-symbols": "1.0.0"
                     }
                 },
                 "is-typedarray": {
@@ -10629,7 +10628,7 @@
                     "version": "3.1.0",
                     "bundled": true,
                     "requires": {
-                        "package-json": "^4.0.0"
+                        "package-json": "4.0.1"
                     }
                 },
                 "lazy-property": {
@@ -10640,102 +10639,102 @@
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "invert-kv": "^1.0.0"
+                        "invert-kv": "1.0.0"
                     }
                 },
                 "libcipm": {
                     "version": "4.0.7",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bin-links": "1.1.6",
+                        "bluebird": "3.5.5",
+                        "figgy-pudding": "3.5.1",
+                        "find-npm-prefix": "1.0.2",
+                        "graceful-fs": "4.2.3",
+                        "ini": "1.3.5",
+                        "lock-verify": "2.1.0",
+                        "mkdirp": "0.5.1",
+                        "npm-lifecycle": "3.1.4",
+                        "npm-logical-tree": "1.2.1",
+                        "npm-package-arg": "6.1.1",
+                        "pacote": "9.5.12",
+                        "read-package-json": "2.1.1",
+                        "rimraf": "2.6.3",
+                        "worker-farm": "1.7.0"
                     }
                 },
                 "libnpm": {
                     "version": "3.0.1",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bin-links": "1.1.6",
+                        "bluebird": "3.5.5",
+                        "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.1.0",
+                        "npm-lifecycle": "3.1.4",
+                        "npm-logical-tree": "1.2.1",
+                        "npm-package-arg": "6.1.1",
+                        "npm-profile": "4.0.2",
+                        "npm-registry-fetch": "4.0.2",
+                        "npmlog": "4.1.2",
+                        "pacote": "9.5.12",
+                        "read-package-json": "2.1.1",
+                        "stringify-package": "1.0.1"
                     }
                 },
                 "libnpmaccess": {
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "get-stream": "^4.0.0",
-                        "npm-package-arg": "^6.1.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "get-stream": "4.1.0",
+                        "npm-package-arg": "6.1.1",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmconfig": {
                     "version": "1.2.1",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "find-up": "^3.0.0",
-                        "ini": "^1.3.5"
+                        "figgy-pudding": "3.5.1",
+                        "find-up": "3.0.0",
+                        "ini": "1.3.5"
                     },
                     "dependencies": {
                         "find-up": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "locate-path": "^3.0.0"
+                                "locate-path": "3.0.0"
                             }
                         },
                         "locate-path": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "p-locate": "^3.0.0",
-                                "path-exists": "^3.0.0"
+                                "p-locate": "3.0.0",
+                                "path-exists": "3.0.0"
                             }
                         },
                         "p-limit": {
                             "version": "2.2.0",
                             "bundled": true,
                             "requires": {
-                                "p-try": "^2.0.0"
+                                "p-try": "2.2.0"
                             }
                         },
                         "p-locate": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "p-limit": "^2.0.0"
+                                "p-limit": "2.2.0"
                             }
                         },
                         "p-try": {
@@ -10748,91 +10747,91 @@
                     "version": "5.0.3",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmorg": {
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmpublish": {
                     "version": "1.1.2",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "lodash.clonedeep": "4.5.0",
+                        "normalize-package-data": "2.5.0",
+                        "npm-package-arg": "6.1.1",
+                        "npm-registry-fetch": "4.0.2",
+                        "semver": "5.7.1",
+                        "ssri": "6.0.1"
                     }
                 },
                 "libnpmsearch": {
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmteam": {
                     "version": "1.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpx": {
                     "version": "10.2.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "dotenv": "5.0.1",
+                        "npm-package-arg": "6.1.1",
+                        "rimraf": "2.6.3",
+                        "safe-buffer": "5.1.2",
+                        "update-notifier": "2.5.0",
+                        "which": "1.3.1",
+                        "y18n": "4.0.0",
+                        "yargs": "11.0.0"
                     }
                 },
                 "locate-path": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "p-locate": "^2.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "2.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "lock-verify": {
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "npm-package-arg": "^6.1.0",
-                        "semver": "^5.4.1"
+                        "npm-package-arg": "6.1.1",
+                        "semver": "5.7.1"
                     }
                 },
                 "lockfile": {
                     "version": "1.0.4",
                     "bundled": true,
                     "requires": {
-                        "signal-exit": "^3.0.2"
+                        "signal-exit": "3.0.2"
                     }
                 },
                 "lodash._baseindexof": {
@@ -10843,8 +10842,8 @@
                     "version": "4.6.0",
                     "bundled": true,
                     "requires": {
-                        "lodash._createset": "~4.0.0",
-                        "lodash._root": "~3.0.0"
+                        "lodash._createset": "4.0.3",
+                        "lodash._root": "3.0.1"
                     }
                 },
                 "lodash._bindcallback": {
@@ -10859,7 +10858,7 @@
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "lodash._getnative": "^3.0.0"
+                        "lodash._getnative": "3.9.1"
                     }
                 },
                 "lodash._createset": {
@@ -10902,31 +10901,31 @@
                     "version": "5.1.1",
                     "bundled": true,
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 },
                 "make-dir": {
                     "version": "1.3.0",
                     "bundled": true,
                     "requires": {
-                        "pify": "^3.0.0"
+                        "pify": "3.0.0"
                     }
                 },
                 "make-fetch-happen": {
                     "version": "5.0.2",
                     "bundled": true,
                     "requires": {
-                        "agentkeepalive": "^3.4.1",
-                        "cacache": "^12.0.0",
-                        "http-cache-semantics": "^3.8.1",
-                        "http-proxy-agent": "^2.1.0",
-                        "https-proxy-agent": "^2.2.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"
+                        "agentkeepalive": "3.5.2",
+                        "cacache": "12.0.3",
+                        "http-cache-semantics": "3.8.1",
+                        "http-proxy-agent": "2.1.0",
+                        "https-proxy-agent": "2.2.4",
+                        "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.2",
+                        "ssri": "6.0.1"
                     }
                 },
                 "meant": {
@@ -10937,7 +10936,7 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "mimic-fn": "^1.0.0"
+                        "mimic-fn": "1.2.0"
                     }
                 },
                 "mime-db": {
@@ -10948,7 +10947,7 @@
                     "version": "2.1.19",
                     "bundled": true,
                     "requires": {
-                        "mime-db": "~1.35.0"
+                        "mime-db": "1.35.0"
                     }
                 },
                 "mimic-fn": {
@@ -10959,7 +10958,7 @@
                     "version": "3.0.4",
                     "bundled": true,
                     "requires": {
-                        "brace-expansion": "^1.1.7"
+                        "brace-expansion": "1.1.11"
                     }
                 },
                 "minimist": {
@@ -10970,15 +10969,15 @@
                     "version": "1.3.3",
                     "bundled": true,
                     "requires": {
-                        "minipass": "^2.9.0"
+                        "minipass": "2.9.0"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -10987,16 +10986,16 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "concat-stream": "^1.5.0",
-                        "duplexify": "^3.4.2",
-                        "end-of-stream": "^1.1.0",
-                        "flush-write-stream": "^1.0.0",
-                        "from2": "^2.1.0",
-                        "parallel-transform": "^1.1.0",
-                        "pump": "^3.0.0",
-                        "pumpify": "^1.3.3",
-                        "stream-each": "^1.1.0",
-                        "through2": "^2.0.0"
+                        "concat-stream": "1.6.2",
+                        "duplexify": "3.6.0",
+                        "end-of-stream": "1.4.1",
+                        "flush-write-stream": "1.0.3",
+                        "from2": "2.3.0",
+                        "parallel-transform": "1.1.0",
+                        "pump": "3.0.0",
+                        "pumpify": "1.5.1",
+                        "stream-each": "1.2.2",
+                        "through2": "2.0.3"
                     }
                 },
                 "mkdirp": {
@@ -11010,12 +11009,12 @@
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1",
-                        "copy-concurrently": "^1.0.0",
-                        "fs-write-stream-atomic": "^1.0.8",
-                        "mkdirp": "^0.5.1",
-                        "rimraf": "^2.5.4",
-                        "run-queue": "^1.0.3"
+                        "aproba": "1.2.0",
+                        "copy-concurrently": "1.0.5",
+                        "fs-write-stream-atomic": "1.0.10",
+                        "mkdirp": "0.5.1",
+                        "rimraf": "2.6.3",
+                        "run-queue": "1.0.3"
                     },
                     "dependencies": {
                         "aproba": {
@@ -11036,33 +11035,33 @@
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "encoding": "^0.1.11",
-                        "json-parse-better-errors": "^1.0.0",
-                        "safe-buffer": "^5.1.1"
+                        "encoding": "0.1.12",
+                        "json-parse-better-errors": "1.0.2",
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "node-gyp": {
                     "version": "5.0.5",
                     "bundled": true,
                     "requires": {
-                        "env-paths": "^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",
-                        "request": "^2.87.0",
-                        "rimraf": "2",
-                        "semver": "~5.3.0",
-                        "tar": "^4.4.12",
-                        "which": "1"
+                        "env-paths": "1.0.0",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "mkdirp": "0.5.1",
+                        "nopt": "3.0.6",
+                        "npmlog": "4.1.2",
+                        "request": "2.88.0",
+                        "rimraf": "2.6.3",
+                        "semver": "5.3.0",
+                        "tar": "4.4.13",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "nopt": {
                             "version": "3.0.6",
                             "bundled": true,
                             "requires": {
-                                "abbrev": "1"
+                                "abbrev": "1.1.1"
                             }
                         },
                         "semver": {
@@ -11075,25 +11074,25 @@
                     "version": "4.0.1",
                     "bundled": true,
                     "requires": {
-                        "abbrev": "1",
-                        "osenv": "^0.1.4"
+                        "abbrev": "1.1.1",
+                        "osenv": "0.1.5"
                     }
                 },
                 "normalize-package-data": {
                     "version": "2.5.0",
                     "bundled": true,
                     "requires": {
-                        "hosted-git-info": "^2.1.4",
-                        "resolve": "^1.10.0",
-                        "semver": "2 || 3 || 4 || 5",
-                        "validate-npm-package-license": "^3.0.1"
+                        "hosted-git-info": "2.8.5",
+                        "resolve": "1.10.0",
+                        "semver": "5.7.1",
+                        "validate-npm-package-license": "3.0.4"
                     },
                     "dependencies": {
                         "resolve": {
                             "version": "1.10.0",
                             "bundled": true,
                             "requires": {
-                                "path-parse": "^1.0.6"
+                                "path-parse": "1.0.6"
                             }
                         }
                     }
@@ -11102,15 +11101,15 @@
                     "version": "1.3.2",
                     "bundled": true,
                     "requires": {
-                        "cli-table3": "^0.5.0",
-                        "console-control-strings": "^1.1.0"
+                        "cli-table3": "0.5.1",
+                        "console-control-strings": "1.1.0"
                     }
                 },
                 "npm-bundled": {
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "npm-normalize-package-bin": "^1.0.1"
+                        "npm-normalize-package-bin": "1.0.1"
                     }
                 },
                 "npm-cache-filename": {
@@ -11121,21 +11120,21 @@
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "semver": "^2.3.0 || 3.x || 4 || 5"
+                        "semver": "5.7.1"
                     }
                 },
                 "npm-lifecycle": {
                     "version": "3.1.4",
                     "bundled": true,
                     "requires": {
-                        "byline": "^5.0.0",
-                        "graceful-fs": "^4.1.15",
-                        "node-gyp": "^5.0.2",
-                        "resolve-from": "^4.0.0",
-                        "slide": "^1.1.6",
+                        "byline": "5.0.0",
+                        "graceful-fs": "4.2.3",
+                        "node-gyp": "5.0.5",
+                        "resolve-from": "4.0.0",
+                        "slide": "1.1.6",
                         "uid-number": "0.0.6",
-                        "umask": "^1.1.0",
-                        "which": "^1.3.1"
+                        "umask": "1.1.0",
+                        "which": "1.3.1"
                     }
                 },
                 "npm-logical-tree": {
@@ -11150,49 +11149,49 @@
                     "version": "6.1.1",
                     "bundled": true,
                     "requires": {
-                        "hosted-git-info": "^2.7.1",
-                        "osenv": "^0.1.5",
-                        "semver": "^5.6.0",
-                        "validate-npm-package-name": "^3.0.0"
+                        "hosted-git-info": "2.8.5",
+                        "osenv": "0.1.5",
+                        "semver": "5.7.1",
+                        "validate-npm-package-name": "3.0.0"
                     }
                 },
                 "npm-packlist": {
                     "version": "1.4.7",
                     "bundled": true,
                     "requires": {
-                        "ignore-walk": "^3.0.1",
-                        "npm-bundled": "^1.0.1"
+                        "ignore-walk": "3.0.3",
+                        "npm-bundled": "1.1.1"
                     }
                 },
                 "npm-pick-manifest": {
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "npm-package-arg": "^6.0.0",
-                        "semver": "^5.4.1"
+                        "figgy-pudding": "3.5.1",
+                        "npm-package-arg": "6.1.1",
+                        "semver": "5.7.1"
                     }
                 },
                 "npm-profile": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.2 || 2",
-                        "figgy-pudding": "^3.4.1",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "npm-registry-fetch": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "JSONStream": "^1.3.4",
-                        "bluebird": "^3.5.1",
-                        "figgy-pudding": "^3.4.1",
-                        "lru-cache": "^5.1.1",
-                        "make-fetch-happen": "^5.0.0",
-                        "npm-package-arg": "^6.1.0",
-                        "safe-buffer": "^5.2.0"
+                        "JSONStream": "1.3.5",
+                        "bluebird": "3.5.5",
+                        "figgy-pudding": "3.5.1",
+                        "lru-cache": "5.1.1",
+                        "make-fetch-happen": "5.0.2",
+                        "npm-package-arg": "6.1.1",
+                        "safe-buffer": "5.2.0"
                     },
                     "dependencies": {
                         "safe-buffer": {
@@ -11205,7 +11204,7 @@
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "path-key": "^2.0.0"
+                        "path-key": "2.0.1"
                     }
                 },
                 "npm-user-validate": {
@@ -11216,10 +11215,10 @@
                     "version": "4.1.2",
                     "bundled": true,
                     "requires": {
-                        "are-we-there-yet": "~1.1.2",
-                        "console-control-strings": "~1.1.0",
-                        "gauge": "~2.7.3",
-                        "set-blocking": "~2.0.0"
+                        "are-we-there-yet": "1.1.4",
+                        "console-control-strings": "1.1.0",
+                        "gauge": "2.7.4",
+                        "set-blocking": "2.0.0"
                     }
                 },
                 "number-is-nan": {
@@ -11242,15 +11241,15 @@
                     "version": "2.0.3",
                     "bundled": true,
                     "requires": {
-                        "define-properties": "^1.1.2",
-                        "es-abstract": "^1.5.1"
+                        "define-properties": "1.1.3",
+                        "es-abstract": "1.12.0"
                     }
                 },
                 "once": {
                     "version": "1.4.0",
                     "bundled": true,
                     "requires": {
-                        "wrappy": "1"
+                        "wrappy": "1.0.2"
                     }
                 },
                 "opener": {
@@ -11265,9 +11264,9 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "execa": "^0.7.0",
-                        "lcid": "^1.0.0",
-                        "mem": "^1.1.0"
+                        "execa": "0.7.0",
+                        "lcid": "1.0.0",
+                        "mem": "1.1.0"
                     }
                 },
                 "os-tmpdir": {
@@ -11278,8 +11277,8 @@
                     "version": "0.1.5",
                     "bundled": true,
                     "requires": {
-                        "os-homedir": "^1.0.0",
-                        "os-tmpdir": "^1.0.0"
+                        "os-homedir": "1.0.2",
+                        "os-tmpdir": "1.0.2"
                     }
                 },
                 "p-finally": {
@@ -11290,14 +11289,14 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 },
                 "p-locate": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "p-limit": "^1.1.0"
+                        "p-limit": "1.2.0"
                     }
                 },
                 "p-try": {
@@ -11308,54 +11307,54 @@
                     "version": "4.0.1",
                     "bundled": true,
                     "requires": {
-                        "got": "^6.7.1",
-                        "registry-auth-token": "^3.0.1",
-                        "registry-url": "^3.0.3",
-                        "semver": "^5.1.0"
+                        "got": "6.7.1",
+                        "registry-auth-token": "3.3.2",
+                        "registry-url": "3.1.0",
+                        "semver": "5.7.1"
                     }
                 },
                 "pacote": {
-                    "version": "9.5.11",
+                    "version": "9.5.12",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "cacache": "12.0.3",
+                        "chownr": "1.1.3",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "glob": "7.1.4",
+                        "infer-owner": "1.0.4",
+                        "lru-cache": "5.1.1",
+                        "make-fetch-happen": "5.0.2",
+                        "minimatch": "3.0.4",
+                        "minipass": "2.9.0",
+                        "mississippi": "3.0.0",
+                        "mkdirp": "0.5.1",
+                        "normalize-package-data": "2.5.0",
+                        "npm-normalize-package-bin": "1.0.1",
+                        "npm-package-arg": "6.1.1",
+                        "npm-packlist": "1.4.7",
+                        "npm-pick-manifest": "3.0.2",
+                        "npm-registry-fetch": "4.0.2",
+                        "osenv": "0.1.5",
+                        "promise-inflight": "1.0.1",
+                        "promise-retry": "1.1.1",
+                        "protoduck": "5.0.1",
+                        "rimraf": "2.6.3",
+                        "safe-buffer": "5.1.2",
+                        "semver": "5.7.1",
+                        "ssri": "6.0.1",
+                        "tar": "4.4.13",
+                        "unique-filename": "1.1.1",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -11364,29 +11363,29 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "cyclist": "~0.2.2",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^2.1.5"
+                        "cyclist": "0.2.2",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -11435,8 +11434,8 @@
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "err-code": "^1.0.0",
-                        "retry": "^0.10.0"
+                        "err-code": "1.1.2",
+                        "retry": "0.10.1"
                     },
                     "dependencies": {
                         "retry": {
@@ -11449,7 +11448,7 @@
                     "version": "0.3.0",
                     "bundled": true,
                     "requires": {
-                        "read": "1"
+                        "read": "1.0.7"
                     }
                 },
                 "proto-list": {
@@ -11460,7 +11459,7 @@
                     "version": "5.0.1",
                     "bundled": true,
                     "requires": {
-                        "genfun": "^5.0.0"
+                        "genfun": "5.0.0"
                     }
                 },
                 "prr": {
@@ -11479,25 +11478,25 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "pumpify": {
                     "version": "1.5.1",
                     "bundled": true,
                     "requires": {
-                        "duplexify": "^3.6.0",
-                        "inherits": "^2.0.3",
-                        "pump": "^2.0.0"
+                        "duplexify": "3.6.0",
+                        "inherits": "2.0.4",
+                        "pump": "2.0.1"
                     },
                     "dependencies": {
                         "pump": {
                             "version": "2.0.1",
                             "bundled": true,
                             "requires": {
-                                "end-of-stream": "^1.1.0",
-                                "once": "^1.3.1"
+                                "end-of-stream": "1.4.1",
+                                "once": "1.4.0"
                             }
                         }
                     }
@@ -11518,9 +11517,9 @@
                     "version": "6.8.2",
                     "bundled": true,
                     "requires": {
-                        "decode-uri-component": "^0.2.0",
-                        "split-on-first": "^1.0.0",
-                        "strict-uri-encode": "^2.0.0"
+                        "decode-uri-component": "0.2.0",
+                        "split-on-first": "1.1.0",
+                        "strict-uri-encode": "2.0.0"
                     }
                 },
                 "qw": {
@@ -11531,10 +11530,10 @@
                     "version": "1.2.7",
                     "bundled": true,
                     "requires": {
-                        "deep-extend": "^0.5.1",
-                        "ini": "~1.3.0",
-                        "minimist": "^1.2.0",
-                        "strip-json-comments": "~2.0.1"
+                        "deep-extend": "0.5.1",
+                        "ini": "1.3.5",
+                        "minimist": "1.2.0",
+                        "strip-json-comments": "2.0.1"
                     },
                     "dependencies": {
                         "minimist": {
@@ -11547,107 +11546,107 @@
                     "version": "1.0.7",
                     "bundled": true,
                     "requires": {
-                        "mute-stream": "~0.0.4"
+                        "mute-stream": "0.0.7"
                     }
                 },
                 "read-cmd-shim": {
                     "version": "1.0.5",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2"
+                        "graceful-fs": "4.2.3"
                     }
                 },
                 "read-installed": {
                     "version": "4.0.3",
                     "bundled": true,
                     "requires": {
-                        "debuglog": "^1.0.1",
-                        "graceful-fs": "^4.1.2",
-                        "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"
+                        "debuglog": "1.0.1",
+                        "graceful-fs": "4.2.3",
+                        "read-package-json": "2.1.1",
+                        "readdir-scoped-modules": "1.1.0",
+                        "semver": "5.7.1",
+                        "slide": "1.1.6",
+                        "util-extend": "1.0.3"
                     }
                 },
                 "read-package-json": {
                     "version": "2.1.1",
                     "bundled": true,
                     "requires": {
-                        "glob": "^7.1.1",
-                        "graceful-fs": "^4.1.2",
-                        "json-parse-better-errors": "^1.0.1",
-                        "normalize-package-data": "^2.0.0",
-                        "npm-normalize-package-bin": "^1.0.0"
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "json-parse-better-errors": "1.0.2",
+                        "normalize-package-data": "2.5.0",
+                        "npm-normalize-package-bin": "1.0.1"
                     }
                 },
                 "read-package-tree": {
                     "version": "5.3.1",
                     "bundled": true,
                     "requires": {
-                        "read-package-json": "^2.0.0",
-                        "readdir-scoped-modules": "^1.0.0",
-                        "util-promisify": "^2.1.0"
+                        "read-package-json": "2.1.1",
+                        "readdir-scoped-modules": "1.1.0",
+                        "util-promisify": "2.1.0"
                     }
                 },
                 "readable-stream": {
                     "version": "3.4.0",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.4",
+                        "string_decoder": "1.2.0",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "readdir-scoped-modules": {
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "debuglog": "^1.0.1",
-                        "dezalgo": "^1.0.0",
-                        "graceful-fs": "^4.1.2",
-                        "once": "^1.3.0"
+                        "debuglog": "1.0.1",
+                        "dezalgo": "1.0.3",
+                        "graceful-fs": "4.2.3",
+                        "once": "1.4.0"
                     }
                 },
                 "registry-auth-token": {
                     "version": "3.3.2",
                     "bundled": true,
                     "requires": {
-                        "rc": "^1.1.6",
-                        "safe-buffer": "^5.0.1"
+                        "rc": "1.2.7",
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "registry-url": {
                     "version": "3.1.0",
                     "bundled": true,
                     "requires": {
-                        "rc": "^1.0.1"
+                        "rc": "1.2.7"
                     }
                 },
                 "request": {
                     "version": "2.88.0",
                     "bundled": true,
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "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.3"
                     }
                 },
                 "require-directory": {
@@ -11670,14 +11669,14 @@
                     "version": "2.6.3",
                     "bundled": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "run-queue": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1"
+                        "aproba": "1.2.0"
                     },
                     "dependencies": {
                         "aproba": {
@@ -11702,7 +11701,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "semver": "^5.0.3"
+                        "semver": "5.7.1"
                     }
                 },
                 "set-blocking": {
@@ -11713,14 +11712,14 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2"
+                        "graceful-fs": "4.2.3"
                     }
                 },
                 "shebang-command": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "shebang-regex": "^1.0.0"
+                        "shebang-regex": "1.0.0"
                     }
                 },
                 "shebang-regex": {
@@ -11744,22 +11743,22 @@
                     "bundled": true,
                     "requires": {
                         "ip": "1.1.5",
-                        "smart-buffer": "^4.1.0"
+                        "smart-buffer": "4.1.0"
                     }
                 },
                 "socks-proxy-agent": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "~4.2.1",
-                        "socks": "~2.3.2"
+                        "agent-base": "4.2.1",
+                        "socks": "2.3.3"
                     },
                     "dependencies": {
                         "agent-base": {
                             "version": "4.2.1",
                             "bundled": true,
                             "requires": {
-                                "es6-promisify": "^5.0.0"
+                                "es6-promisify": "5.0.0"
                             }
                         }
                     }
@@ -11772,16 +11771,16 @@
                     "version": "2.1.3",
                     "bundled": true,
                     "requires": {
-                        "from2": "^1.3.0",
-                        "stream-iterate": "^1.1.0"
+                        "from2": "1.3.0",
+                        "stream-iterate": "1.2.0"
                     },
                     "dependencies": {
                         "from2": {
                             "version": "1.3.0",
                             "bundled": true,
                             "requires": {
-                                "inherits": "~2.0.1",
-                                "readable-stream": "~1.1.10"
+                                "inherits": "2.0.4",
+                                "readable-stream": "1.1.14"
                             }
                         },
                         "isarray": {
@@ -11792,10 +11791,10 @@
                             "version": "1.1.14",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.1",
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
                                 "isarray": "0.0.1",
-                                "string_decoder": "~0.10.x"
+                                "string_decoder": "0.10.31"
                             }
                         },
                         "string_decoder": {
@@ -11808,8 +11807,8 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "spdx-expression-parse": "^3.0.0",
-                        "spdx-license-ids": "^3.0.0"
+                        "spdx-expression-parse": "3.0.0",
+                        "spdx-license-ids": "3.0.3"
                     }
                 },
                 "spdx-exceptions": {
@@ -11820,8 +11819,8 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "spdx-exceptions": "^2.1.0",
-                        "spdx-license-ids": "^3.0.0"
+                        "spdx-exceptions": "2.1.0",
+                        "spdx-license-ids": "3.0.3"
                     }
                 },
                 "spdx-license-ids": {
@@ -11836,58 +11835,58 @@
                     "version": "1.14.2",
                     "bundled": true,
                     "requires": {
-                        "asn1": "~0.2.3",
-                        "assert-plus": "^1.0.0",
-                        "bcrypt-pbkdf": "^1.0.0",
-                        "dashdash": "^1.12.0",
-                        "ecc-jsbn": "~0.1.1",
-                        "getpass": "^0.1.1",
-                        "jsbn": "~0.1.0",
-                        "safer-buffer": "^2.0.2",
-                        "tweetnacl": "~0.14.0"
+                        "asn1": "0.2.4",
+                        "assert-plus": "1.0.0",
+                        "bcrypt-pbkdf": "1.0.2",
+                        "dashdash": "1.14.1",
+                        "ecc-jsbn": "0.1.2",
+                        "getpass": "0.1.7",
+                        "jsbn": "0.1.1",
+                        "safer-buffer": "2.1.2",
+                        "tweetnacl": "0.14.5"
                     }
                 },
                 "ssri": {
                     "version": "6.0.1",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1"
+                        "figgy-pudding": "3.5.1"
                     }
                 },
                 "stream-each": {
                     "version": "1.2.2",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "stream-shift": "^1.0.0"
+                        "end-of-stream": "1.4.1",
+                        "stream-shift": "1.0.0"
                     }
                 },
                 "stream-iterate": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "readable-stream": "^2.1.5",
-                        "stream-shift": "^1.0.0"
+                        "readable-stream": "2.3.6",
+                        "stream-shift": "1.0.0"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -11904,8 +11903,8 @@
                     "version": "2.1.1",
                     "bundled": true,
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     },
                     "dependencies": {
                         "ansi-regex": {
@@ -11920,7 +11919,7 @@
                             "version": "4.0.0",
                             "bundled": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -11929,7 +11928,7 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "stringify-package": {
@@ -11940,7 +11939,7 @@
                     "version": "3.0.1",
                     "bundled": true,
                     "requires": {
-                        "ansi-regex": "^2.0.0"
+                        "ansi-regex": "2.1.1"
                     }
                 },
                 "strip-eof": {
@@ -11955,28 +11954,28 @@
                     "version": "5.4.0",
                     "bundled": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "tar": {
                     "version": "4.4.13",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "chownr": "1.1.3",
+                        "fs-minipass": "1.2.7",
+                        "minipass": "2.9.0",
+                        "minizlib": "1.3.3",
+                        "mkdirp": "0.5.1",
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.0.3"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -11985,7 +11984,7 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "execa": "^0.7.0"
+                        "execa": "0.7.0"
                     }
                 },
                 "text-table": {
@@ -12000,28 +11999,28 @@
                     "version": "2.0.3",
                     "bundled": true,
                     "requires": {
-                        "readable-stream": "^2.1.5",
-                        "xtend": "~4.0.1"
+                        "readable-stream": "2.3.6",
+                        "xtend": "4.0.1"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -12038,15 +12037,15 @@
                     "version": "2.4.3",
                     "bundled": true,
                     "requires": {
-                        "psl": "^1.1.24",
-                        "punycode": "^1.4.1"
+                        "psl": "1.1.29",
+                        "punycode": "1.4.1"
                     }
                 },
                 "tunnel-agent": {
                     "version": "0.6.0",
                     "bundled": true,
                     "requires": {
-                        "safe-buffer": "^5.0.1"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "tweetnacl": {
@@ -12070,21 +12069,21 @@
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "unique-slug": "^2.0.0"
+                        "unique-slug": "2.0.0"
                     }
                 },
                 "unique-slug": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "imurmurhash": "^0.1.4"
+                        "imurmurhash": "0.1.4"
                     }
                 },
                 "unique-string": {
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "crypto-random-string": "^1.0.0"
+                        "crypto-random-string": "1.0.0"
                     }
                 },
                 "unpipe": {
@@ -12099,23 +12098,23 @@
                     "version": "2.5.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "boxen": "1.3.0",
+                        "chalk": "2.4.1",
+                        "configstore": "3.1.2",
+                        "import-lazy": "2.1.0",
+                        "is-ci": "1.1.0",
+                        "is-installed-globally": "0.1.0",
+                        "is-npm": "1.0.0",
+                        "latest-version": "3.1.0",
+                        "semver-diff": "2.1.0",
+                        "xdg-basedir": "3.0.0"
                     }
                 },
                 "url-parse-lax": {
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "prepend-http": "^1.0.1"
+                        "prepend-http": "1.0.4"
                     }
                 },
                 "util-deprecate": {
@@ -12130,7 +12129,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "object.getownpropertydescriptors": "^2.0.3"
+                        "object.getownpropertydescriptors": "2.0.3"
                     }
                 },
                 "uuid": {
@@ -12141,38 +12140,38 @@
                     "version": "3.0.4",
                     "bundled": true,
                     "requires": {
-                        "spdx-correct": "^3.0.0",
-                        "spdx-expression-parse": "^3.0.0"
+                        "spdx-correct": "3.0.0",
+                        "spdx-expression-parse": "3.0.0"
                     }
                 },
                 "validate-npm-package-name": {
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "builtins": "^1.0.3"
+                        "builtins": "1.0.3"
                     }
                 },
                 "verror": {
                     "version": "1.10.0",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0",
+                        "assert-plus": "1.0.0",
                         "core-util-is": "1.0.2",
-                        "extsprintf": "^1.2.0"
+                        "extsprintf": "1.3.0"
                     }
                 },
                 "wcwidth": {
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "defaults": "^1.0.3"
+                        "defaults": "1.0.3"
                     }
                 },
                 "which": {
                     "version": "1.3.1",
                     "bundled": true,
                     "requires": {
-                        "isexe": "^2.0.0"
+                        "isexe": "2.0.0"
                     }
                 },
                 "which-module": {
@@ -12183,16 +12182,16 @@
                     "version": "1.1.2",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^1.0.2"
+                        "string-width": "1.0.2"
                     },
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -12201,31 +12200,31 @@
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.1.1"
+                        "string-width": "2.1.1"
                     }
                 },
                 "worker-farm": {
                     "version": "1.7.0",
                     "bundled": true,
                     "requires": {
-                        "errno": "~0.1.7"
+                        "errno": "0.1.7"
                     }
                 },
                 "wrap-ansi": {
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1"
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1"
                     },
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -12238,9 +12237,9 @@
                     "version": "2.4.3",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.11",
-                        "imurmurhash": "^0.1.4",
-                        "signal-exit": "^3.0.2"
+                        "graceful-fs": "4.2.3",
+                        "imurmurhash": "0.1.4",
+                        "signal-exit": "3.0.2"
                     }
                 },
                 "xdg-basedir": {
@@ -12263,18 +12262,18 @@
                     "version": "11.0.0",
                     "bundled": true,
                     "requires": {
-                        "cliui": "^4.0.0",
-                        "decamelize": "^1.1.1",
-                        "find-up": "^2.1.0",
-                        "get-caller-file": "^1.0.1",
-                        "os-locale": "^2.0.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^1.0.1",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^2.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^3.2.1",
-                        "yargs-parser": "^9.0.2"
+                        "cliui": "4.1.0",
+                        "decamelize": "1.2.0",
+                        "find-up": "2.1.0",
+                        "get-caller-file": "1.0.2",
+                        "os-locale": "2.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "1.0.1",
+                        "set-blocking": "2.0.0",
+                        "string-width": "2.1.1",
+                        "which-module": "2.0.0",
+                        "y18n": "3.2.1",
+                        "yargs-parser": "9.0.2"
                     },
                     "dependencies": {
                         "y18n": {
@@ -12287,7 +12286,7 @@
                     "version": "9.0.2",
                     "bundled": true,
                     "requires": {
-                        "camelcase": "^4.1.0"
+                        "camelcase": "4.1.0"
                     }
                 }
             }
@@ -12302,8 +12301,8 @@
             "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz",
             "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==",
             "requires": {
-                "ignore-walk": "^3.0.1",
-                "npm-bundled": "^1.0.1"
+                "ignore-walk": "3.0.1",
+                "npm-bundled": "1.0.6"
             }
         },
         "npm-run-path": {
@@ -12311,7 +12310,7 @@
             "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
             "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
             "requires": {
-                "path-key": "^2.0.0"
+                "path-key": "2.0.1"
             }
         },
         "npmlog": {
@@ -12319,10 +12318,10 @@
             "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
             "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
             "requires": {
-                "are-we-there-yet": "~1.1.2",
-                "console-control-strings": "~1.1.0",
-                "gauge": "~2.7.3",
-                "set-blocking": "~2.0.0"
+                "are-we-there-yet": "1.1.5",
+                "console-control-strings": "1.1.0",
+                "gauge": "2.7.4",
+                "set-blocking": "2.0.0"
             }
         },
         "nth-check": {
@@ -12330,7 +12329,7 @@
             "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
             "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
             "requires": {
-                "boolbase": "~1.0.0"
+                "boolbase": "1.0.0"
             }
         },
         "number-is-nan": {
@@ -12369,9 +12368,9 @@
             "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
             "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
             "requires": {
-                "copy-descriptor": "^0.1.0",
-                "define-property": "^0.2.5",
-                "kind-of": "^3.0.3"
+                "copy-descriptor": "0.1.1",
+                "define-property": "0.2.5",
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "define-property": {
@@ -12379,7 +12378,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "kind-of": {
@@ -12387,7 +12386,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -12430,10 +12429,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -12443,7 +12442,7 @@
             "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
             "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
             "requires": {
-                "isobject": "^3.0.0"
+                "isobject": "3.0.1"
             }
         },
         "object.assign": {
@@ -12451,10 +12450,10 @@
             "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
             "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
             "requires": {
-                "define-properties": "^1.1.2",
-                "function-bind": "^1.1.1",
-                "has-symbols": "^1.0.0",
-                "object-keys": "^1.0.11"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1",
+                "has-symbols": "1.0.0",
+                "object-keys": "1.1.1"
             }
         },
         "object.getownpropertydescriptors": {
@@ -12462,8 +12461,8 @@
             "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
             "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
             "requires": {
-                "define-properties": "^1.1.2",
-                "es-abstract": "^1.5.1"
+                "define-properties": "1.1.3",
+                "es-abstract": "1.16.0"
             }
         },
         "object.pick": {
@@ -12471,7 +12470,7 @@
             "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
             "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
             "requires": {
-                "isobject": "^3.0.1"
+                "isobject": "3.0.1"
             }
         },
         "obuf": {
@@ -12498,7 +12497,7 @@
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
             "requires": {
-                "wrappy": "1"
+                "wrappy": "1.0.2"
             }
         },
         "opn": {
@@ -12507,7 +12506,7 @@
             "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
             "dev": true,
             "requires": {
-                "is-wsl": "^1.1.0"
+                "is-wsl": "1.1.0"
             }
         },
         "optionator": {
@@ -12516,12 +12515,12 @@
             "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
             "dev": true,
             "requires": {
-                "deep-is": "~0.1.3",
-                "fast-levenshtein": "~2.0.4",
-                "levn": "~0.3.0",
-                "prelude-ls": "~1.1.2",
-                "type-check": "~0.3.2",
-                "wordwrap": "~1.0.0"
+                "deep-is": "0.1.3",
+                "fast-levenshtein": "2.0.6",
+                "levn": "0.3.0",
+                "prelude-ls": "1.1.2",
+                "type-check": "0.3.2",
+                "wordwrap": "1.0.0"
             },
             "dependencies": {
                 "wordwrap": {
@@ -12543,7 +12542,7 @@
             "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
             "dev": true,
             "requires": {
-                "url-parse": "^1.4.3"
+                "url-parse": "1.4.7"
             }
         },
         "os-browserify": {
@@ -12562,7 +12561,7 @@
             "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
             "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
             "requires": {
-                "lcid": "^1.0.0"
+                "lcid": "1.0.0"
             }
         },
         "os-tmpdir": {
@@ -12575,8 +12574,8 @@
             "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
             "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
             "requires": {
-                "os-homedir": "^1.0.0",
-                "os-tmpdir": "^1.0.0"
+                "os-homedir": "1.0.2",
+                "os-tmpdir": "1.0.2"
             }
         },
         "p-defer": {
@@ -12601,7 +12600,7 @@
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
             "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
             "requires": {
-                "p-try": "^2.0.0"
+                "p-try": "2.2.0"
             },
             "dependencies": {
                 "p-try": {
@@ -12616,7 +12615,7 @@
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
             "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
             "requires": {
-                "p-limit": "^1.1.0"
+                "p-limit": "1.3.0"
             },
             "dependencies": {
                 "p-limit": {
@@ -12624,7 +12623,7 @@
                     "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
                     "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 }
             }
@@ -12641,7 +12640,7 @@
             "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
             "dev": true,
             "requires": {
-                "retry": "^0.12.0"
+                "retry": "0.12.0"
             }
         },
         "p-try": {
@@ -12654,10 +12653,10 @@
             "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
             "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
             "requires": {
-                "got": "^6.7.1",
-                "registry-auth-token": "^3.0.1",
-                "registry-url": "^3.0.3",
-                "semver": "^5.1.0"
+                "got": "6.7.1",
+                "registry-auth-token": "3.4.0",
+                "registry-url": "3.1.0",
+                "semver": "5.7.0"
             }
         },
         "pako": {
@@ -12672,9 +12671,9 @@
             "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
             "dev": true,
             "requires": {
-                "cyclist": "~0.2.2",
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.1.5"
+                "cyclist": "0.2.2",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "parent-module": {
@@ -12682,7 +12681,7 @@
             "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
             "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
             "requires": {
-                "callsites": "^3.0.0"
+                "callsites": "3.1.0"
             }
         },
         "parse-asn1": {
@@ -12690,12 +12689,12 @@
             "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
             "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
             "requires": {
-                "asn1.js": "^4.0.0",
-                "browserify-aes": "^1.0.0",
-                "create-hash": "^1.1.0",
-                "evp_bytestokey": "^1.0.0",
-                "pbkdf2": "^3.0.3",
-                "safe-buffer": "^5.1.1"
+                "asn1.js": "4.10.1",
+                "browserify-aes": "1.2.0",
+                "create-hash": "1.2.0",
+                "evp_bytestokey": "1.0.3",
+                "pbkdf2": "3.0.17",
+                "safe-buffer": "5.1.2"
             }
         },
         "parse-json": {
@@ -12703,10 +12702,10 @@
             "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
             "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
             "requires": {
-                "@babel/code-frame": "^7.0.0",
-                "error-ex": "^1.3.1",
-                "json-parse-better-errors": "^1.0.1",
-                "lines-and-columns": "^1.1.6"
+                "@babel/code-frame": "7.5.5",
+                "error-ex": "1.3.2",
+                "json-parse-better-errors": "1.0.2",
+                "lines-and-columns": "1.1.6"
             }
         },
         "parse-passwd": {
@@ -12726,7 +12725,7 @@
             "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
             "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
             "requires": {
-                "better-assert": "~1.0.0"
+                "better-assert": "1.0.2"
             }
         },
         "parseuri": {
@@ -12734,7 +12733,7 @@
             "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
             "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
             "requires": {
-                "better-assert": "~1.0.0"
+                "better-assert": "1.0.2"
             }
         },
         "parseurl": {
@@ -12752,7 +12751,7 @@
             "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz",
             "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=",
             "requires": {
-                "passport-strategy": "1.x.x",
+                "passport-strategy": "1.0.0",
                 "pause": "0.0.1"
             }
         },
@@ -12761,7 +12760,7 @@
             "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
             "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
             "requires": {
-                "passport-oauth2": "1.x.x"
+                "passport-oauth2": "1.5.0"
             }
         },
         "passport-local": {
@@ -12769,7 +12768,7 @@
             "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
             "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
             "requires": {
-                "passport-strategy": "1.x.x"
+                "passport-strategy": "1.0.0"
             }
         },
         "passport-oauth2": {
@@ -12777,11 +12776,11 @@
             "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz",
             "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==",
             "requires": {
-                "base64url": "3.x.x",
-                "oauth": "0.9.x",
-                "passport-strategy": "1.x.x",
-                "uid2": "0.0.x",
-                "utils-merge": "1.x.x"
+                "base64url": "3.0.1",
+                "oauth": "0.9.15",
+                "passport-strategy": "1.0.0",
+                "uid2": "0.0.3",
+                "utils-merge": "1.0.1"
             }
         },
         "passport-strategy": {
@@ -12835,9 +12834,9 @@
             "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
             "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "pify": "^2.0.0",
-                "pinkie-promise": "^2.0.0"
+                "graceful-fs": "4.2.0",
+                "pify": "2.3.0",
+                "pinkie-promise": "2.0.1"
             }
         },
         "pathval": {
@@ -12855,11 +12854,11 @@
             "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
             "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
             "requires": {
-                "create-hash": "^1.1.2",
-                "create-hmac": "^1.1.4",
-                "ripemd160": "^2.0.1",
-                "safe-buffer": "^5.0.1",
-                "sha.js": "^2.4.8"
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "ripemd160": "2.0.2",
+                "safe-buffer": "5.1.2",
+                "sha.js": "2.4.11"
             }
         },
         "pdf-parse": {
@@ -12867,8 +12866,8 @@
             "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz",
             "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==",
             "requires": {
-                "debug": "^3.1.0",
-                "node-ensure": "^0.0.0"
+                "debug": "3.2.6",
+                "node-ensure": "0.0.0"
             },
             "dependencies": {
                 "debug": {
@@ -12876,7 +12875,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -12891,8 +12890,8 @@
             "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.1.266.tgz",
             "integrity": "sha512-Jy7o1wE3NezPxozexSbq4ltuLT0Z21ew/qrEiAEeUZzHxMHGk4DUV1D7RuCXg5vJDvHmjX1YssN+we9QfRRgXQ==",
             "requires": {
-                "node-ensure": "^0.0.0",
-                "worker-loader": "^2.0.0"
+                "node-ensure": "0.0.0",
+                "worker-loader": "2.0.0"
             }
         },
         "performance-now": {
@@ -12915,7 +12914,7 @@
             "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
             "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
             "requires": {
-                "pinkie": "^2.0.0"
+                "pinkie": "2.0.4"
             }
         },
         "pipe-functions": {
@@ -12929,7 +12928,7 @@
             "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
             "dev": true,
             "requires": {
-                "find-up": "^2.1.0"
+                "find-up": "2.1.0"
             }
         },
         "pn": {
@@ -12949,9 +12948,9 @@
             "integrity": "sha512-ESabpDCzmBS3ekHbmpAIiESq3udRsCBGiBZLsC+HgBKv2ezb0R4oG+7RnYEVZ/ZCfhel5Tx3UzdNWA0Lox2QCA==",
             "dev": true,
             "requires": {
-                "async": "^1.5.2",
-                "debug": "^2.2.0",
-                "mkdirp": "0.5.x"
+                "async": "1.5.2",
+                "debug": "2.6.9",
+                "mkdirp": "0.5.1"
             },
             "dependencies": {
                 "async": {
@@ -12973,9 +12972,9 @@
             "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==",
             "dev": true,
             "requires": {
-                "chalk": "^2.4.2",
-                "source-map": "^0.6.1",
-                "supports-color": "^6.1.0"
+                "chalk": "2.4.2",
+                "source-map": "0.6.1",
+                "supports-color": "6.1.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -12984,7 +12983,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -12993,9 +12992,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     },
                     "dependencies": {
                         "supports-color": {
@@ -13004,7 +13003,7 @@
                             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                             "dev": true,
                             "requires": {
-                                "has-flag": "^3.0.0"
+                                "has-flag": "3.0.0"
                             }
                         }
                     }
@@ -13021,7 +13020,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -13032,7 +13031,7 @@
             "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.5"
+                "postcss": "7.0.17"
             }
         },
         "postcss-modules-local-by-default": {
@@ -13041,9 +13040,9 @@
             "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.6",
-                "postcss-selector-parser": "^6.0.0",
-                "postcss-value-parser": "^3.3.1"
+                "postcss": "7.0.17",
+                "postcss-selector-parser": "6.0.2",
+                "postcss-value-parser": "3.3.1"
             }
         },
         "postcss-modules-scope": {
@@ -13052,8 +13051,8 @@
             "integrity": "sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.6",
-                "postcss-selector-parser": "^6.0.0"
+                "postcss": "7.0.17",
+                "postcss-selector-parser": "6.0.2"
             }
         },
         "postcss-modules-values": {
@@ -13062,8 +13061,8 @@
             "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==",
             "dev": true,
             "requires": {
-                "icss-replace-symbols": "^1.1.0",
-                "postcss": "^7.0.6"
+                "icss-replace-symbols": "1.1.0",
+                "postcss": "7.0.17"
             }
         },
         "postcss-selector-parser": {
@@ -13072,9 +13071,9 @@
             "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
             "dev": true,
             "requires": {
-                "cssesc": "^3.0.0",
-                "indexes-of": "^1.0.1",
-                "uniq": "^1.0.1"
+                "cssesc": "3.0.0",
+                "indexes-of": "1.0.1",
+                "uniq": "1.0.1"
             }
         },
         "postcss-value-parser": {
@@ -13088,22 +13087,22 @@
             "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.0.tgz",
             "integrity": "sha512-aaLVANlj4HgZweKttFNUVNRxDukytuIuxeK2boIMHjagNJCiVKWFsKF4tCE3ql3GbrD2tExPQ7/pwtEJcHNZeg==",
             "requires": {
-                "detect-libc": "^1.0.3",
-                "expand-template": "^2.0.3",
+                "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",
-                "os-homedir": "^1.0.1",
-                "pump": "^2.0.1",
-                "rc": "^1.2.7",
-                "simple-get": "^2.7.0",
-                "tar-fs": "^1.13.0",
-                "tunnel-agent": "^0.6.0",
-                "which-pm-runs": "^1.0.0"
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "napi-build-utils": "1.0.1",
+                "node-abi": "2.9.0",
+                "noop-logger": "0.1.1",
+                "npmlog": "4.1.2",
+                "os-homedir": "1.0.2",
+                "pump": "2.0.1",
+                "rc": "1.2.8",
+                "simple-get": "2.8.1",
+                "tar-fs": "1.16.3",
+                "tunnel-agent": "0.6.0",
+                "which-pm-runs": "1.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -13116,9 +13115,9 @@
                     "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
                     "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
                     "requires": {
-                        "decompress-response": "^3.3.0",
-                        "once": "^1.3.1",
-                        "simple-concat": "^1.0.0"
+                        "decompress-response": "3.3.0",
+                        "once": "1.4.0",
+                        "simple-concat": "1.0.0"
                     }
                 }
             }
@@ -13144,12 +13143,12 @@
             "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-4.1.1.tgz",
             "integrity": "sha512-42LqKZqTLxH/UvAZ2/cKhAsR4G/Y6B7i7fI2qtQu9hRBK4YjS6gqO+QRtwTjvojUx4+/+JuOMzLoFyRecT9qRw==",
             "requires": {
-                "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"
+                "any-promise": "1.3.0",
+                "deepmerge": "4.0.0",
+                "inherits": "2.0.3",
+                "next-tick": "1.0.0",
+                "request": "2.88.0",
+                "stream-parser": "0.3.1"
             },
             "dependencies": {
                 "assert-plus": {
@@ -13177,9 +13176,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -13187,8 +13186,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -13196,9 +13195,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -13216,26 +13215,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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"
                     }
                 }
             }
@@ -13256,7 +13255,7 @@
             "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
             "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
             "requires": {
-                "asap": "~2.0.3"
+                "asap": "2.0.6"
             }
         },
         "promise-inflight": {
@@ -13270,9 +13269,9 @@
             "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
             "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
             "requires": {
-                "loose-envify": "^1.4.0",
-                "object-assign": "^4.1.1",
-                "react-is": "^16.8.1"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "react-is": "16.8.6"
             }
         },
         "prop-types-extra": {
@@ -13280,8 +13279,8 @@
             "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz",
             "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==",
             "requires": {
-                "react-is": "^16.3.2",
-                "warning": "^3.0.0"
+                "react-is": "16.8.6",
+                "warning": "3.0.0"
             }
         },
         "prosemirror-commands": {
@@ -13289,9 +13288,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.0.8.tgz",
             "integrity": "sha512-P9QdkYYBHWsrJ1JztQuHgeZS7DPCcijQduOj9oxFiqK8Fm6eTsVHzU1IwiRBe+FlK7tyQaerhu/F5K8sqnZ1Cw==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.7.2",
+                "prosemirror-state": "1.2.4",
+                "prosemirror-transform": "1.1.4"
             }
         },
         "prosemirror-dropcursor": {
@@ -13299,9 +13298,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.1.1.tgz",
             "integrity": "sha512-GeUyMO/tOEf8MXrP7Xb7UIMrfK86OGh0fnyBrHfhav4VjY9cw65mNoqHy87CklE5711AhCP5Qzfp8RL/hVKusg==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.1.0",
-                "prosemirror-view": "^1.1.0"
+                "prosemirror-state": "1.2.4",
+                "prosemirror-transform": "1.1.4",
+                "prosemirror-view": "1.10.3"
             }
         },
         "prosemirror-example-setup": {
@@ -13309,15 +13308,15 @@
             "resolved": "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.0.1.tgz",
             "integrity": "sha512-4NKWpdmm75Zzgq/dIrypRnkBNPx+ONKyoGF42a9g3VIVv0TWglf1CBNxt5kzCgli9xdfut/xE5B42F9DR6BLHw==",
             "requires": {
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-dropcursor": "^1.0.0",
-                "prosemirror-gapcursor": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-inputrules": "^1.0.0",
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-menu": "^1.0.0",
-                "prosemirror-schema-list": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
+                "prosemirror-commands": "1.0.8",
+                "prosemirror-dropcursor": "1.1.1",
+                "prosemirror-gapcursor": "1.0.4",
+                "prosemirror-history": "1.0.4",
+                "prosemirror-inputrules": "1.0.4",
+                "prosemirror-keymap": "1.0.1",
+                "prosemirror-menu": "1.0.5",
+                "prosemirror-schema-list": "1.0.3",
+                "prosemirror-state": "1.2.4"
             }
         },
         "prosemirror-find-replace": {
@@ -13330,10 +13329,10 @@
             "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.0.4.tgz",
             "integrity": "sha512-k021MtJibWs3NaJI6S9tCXfTZ/kaugFZBndHkkWx3Zfk0QDUO6JfVATpflxADN6DUkRwJ7qWyHlLDWu71hxHFQ==",
             "requires": {
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-view": "^1.0.0"
+                "prosemirror-keymap": "1.0.1",
+                "prosemirror-model": "1.7.2",
+                "prosemirror-state": "1.2.4",
+                "prosemirror-view": "1.10.3"
             }
         },
         "prosemirror-history": {
@@ -13341,9 +13340,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.0.4.tgz",
             "integrity": "sha512-Kk2UisC9EzYcsNv+ILiQJWpsu0rbT6+oAAkvseFUHnudtfkmYAJu1+Xp3F0xTTCVmQdSqSLVk8qydllXUUOU4Q==",
             "requires": {
-                "prosemirror-state": "^1.2.2",
-                "prosemirror-transform": "^1.0.0",
-                "rope-sequence": "^1.2.0"
+                "prosemirror-state": "1.2.4",
+                "prosemirror-transform": "1.1.4",
+                "rope-sequence": "1.2.2"
             }
         },
         "prosemirror-inputrules": {
@@ -13351,8 +13350,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.0.4.tgz",
             "integrity": "sha512-RhuBghqUgYWm8ai/P+k1lMl1ZGvt6Cs3Xeur8oN0L1Yy+Z5GmsTp3fT8RVl+vJeGkItEAxAit9Qh7yZxixX7rA==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-state": "1.2.4",
+                "prosemirror-transform": "1.1.4"
             }
         },
         "prosemirror-keymap": {
@@ -13360,8 +13359,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
             "integrity": "sha512-e79ApE7PXXZMFtPz7WbjycjAFd1NPjgY1MkecVz98tqwlBSggXWXYQnWFk6x7UkmnBYRHHbXHkR/RXmu2wyBJg==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "w3c-keyname": "^1.1.8"
+                "prosemirror-state": "1.2.4",
+                "w3c-keyname": "1.1.8"
             }
         },
         "prosemirror-menu": {
@@ -13369,10 +13368,10 @@
             "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.0.5.tgz",
             "integrity": "sha512-9Vrn7CC191v7FA4QrAkL8W1SrR73V3CRIYCDuk94R8oFVk4VxSFdoKVLHuvGzxZ8b5LCu3DMJfh86YW9uL4RkQ==",
             "requires": {
-                "crel": "^3.0.0",
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
+                "crel": "3.1.0",
+                "prosemirror-commands": "1.0.8",
+                "prosemirror-history": "1.0.4",
+                "prosemirror-state": "1.2.4"
             }
         },
         "prosemirror-model": {
@@ -13380,7 +13379,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.7.2.tgz",
             "integrity": "sha512-mopozod/qNTB6utEyY8q4w1nCLDakpr39d8smzHno/wuAivCzBU8HkC9YOx1MBdTcTU6sXiIEh08hQfkC3damw==",
             "requires": {
-                "orderedmap": "^1.0.0"
+                "orderedmap": "1.0.0"
             }
         },
         "prosemirror-schema-basic": {
@@ -13388,7 +13387,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.0.1.tgz",
             "integrity": "sha512-LFO/+zr7RSRJ95k6QGHdAwxsTsB3xxSCphU2Xkg6hNroblUV0rYelKe6s5uM5rdyPUdTTRTPjnZWQE28YsGVcA==",
             "requires": {
-                "prosemirror-model": "^1.2.0"
+                "prosemirror-model": "1.7.2"
             }
         },
         "prosemirror-schema-list": {
@@ -13396,8 +13395,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.0.3.tgz",
             "integrity": "sha512-+zzSawVds8LsZpl/bLTCYk2lYactF93W219Czh81zBILikCRDOHjp1CQ1os4ZXBp6LlD+JnBqF1h59Q+hilOoQ==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.7.2",
+                "prosemirror-transform": "1.1.4"
             }
         },
         "prosemirror-state": {
@@ -13405,8 +13404,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.2.4.tgz",
             "integrity": "sha512-ViXpXond3BbSL12ENARQGq3Y8igwFMbTcy96xUNK8kfIcfQRlYlgYrBPXIkHC5+QZtbPrYlpuJ2+QyeSlSX9Cw==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.7.2",
+                "prosemirror-transform": "1.1.4"
             }
         },
         "prosemirror-transform": {
@@ -13414,7 +13413,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.1.4.tgz",
             "integrity": "sha512-1Y3XuaFJtwusYDvojcCxi3VZvNIntPVoh/dpeVaIM5Vf1V+M6xiIWcDgktUWWRovMxEhdibnpt5eyFmYJJhHtQ==",
             "requires": {
-                "prosemirror-model": "^1.0.0"
+                "prosemirror-model": "1.7.2"
             }
         },
         "prosemirror-view": {
@@ -13422,9 +13421,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.10.3.tgz",
             "integrity": "sha512-3R5iTItRmE1wWZ3X5pbl4j2H6gElTr7Hcr6wTS0QuRlqE9xROcP6BPQuBxaOANgzUOiU8Skw42GCI8Xc/d9Y/A==",
             "requires": {
-                "prosemirror-model": "^1.1.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.1.0"
+                "prosemirror-model": "1.7.2",
+                "prosemirror-state": "1.2.4",
+                "prosemirror-transform": "1.1.4"
             }
         },
         "proxy-addr": {
@@ -13432,7 +13431,7 @@
             "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
             "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
             "requires": {
-                "forwarded": "~0.1.2",
+                "forwarded": "0.1.2",
                 "ipaddr.js": "1.9.0"
             }
         },
@@ -13462,12 +13461,12 @@
             "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
             "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "browserify-rsa": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "parse-asn1": "^5.0.0",
-                "randombytes": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "bn.js": "4.11.8",
+                "browserify-rsa": "4.0.1",
+                "create-hash": "1.2.0",
+                "parse-asn1": "5.1.4",
+                "randombytes": "2.1.0",
+                "safe-buffer": "5.1.2"
             }
         },
         "pug": {
@@ -13475,14 +13474,14 @@
             "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
             "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
             "requires": {
-                "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"
+                "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"
             }
         },
         "pug-attrs": {
@@ -13490,9 +13489,9 @@
             "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz",
             "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==",
             "requires": {
-                "constantinople": "^3.0.1",
-                "js-stringify": "^1.0.1",
-                "pug-runtime": "^2.0.5"
+                "constantinople": "3.1.2",
+                "js-stringify": "1.0.2",
+                "pug-runtime": "2.0.5"
             }
         },
         "pug-code-gen": {
@@ -13500,14 +13499,14 @@
             "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
             "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
             "requires": {
-                "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"
+                "constantinople": "3.1.2",
+                "doctypes": "1.1.0",
+                "js-stringify": "1.0.2",
+                "pug-attrs": "2.0.4",
+                "pug-error": "1.3.3",
+                "pug-runtime": "2.0.5",
+                "void-elements": "2.0.1",
+                "with": "5.1.1"
             }
         },
         "pug-error": {
@@ -13520,13 +13519,13 @@
             "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
             "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
             "requires": {
-                "clean-css": "^4.1.11",
-                "constantinople": "^3.0.1",
+                "clean-css": "4.2.1",
+                "constantinople": "3.1.2",
                 "jstransformer": "1.0.0",
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8",
-                "resolve": "^1.1.6",
-                "uglify-js": "^2.6.1"
+                "pug-error": "1.3.3",
+                "pug-walk": "1.1.8",
+                "resolve": "1.11.1",
+                "uglify-js": "2.8.29"
             }
         },
         "pug-lexer": {
@@ -13534,9 +13533,9 @@
             "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz",
             "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==",
             "requires": {
-                "character-parser": "^2.1.1",
-                "is-expression": "^3.0.0",
-                "pug-error": "^1.3.3"
+                "character-parser": "2.2.0",
+                "is-expression": "3.0.0",
+                "pug-error": "1.3.3"
             }
         },
         "pug-linker": {
@@ -13544,8 +13543,8 @@
             "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
             "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
             "requires": {
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8"
+                "pug-error": "1.3.3",
+                "pug-walk": "1.1.8"
             }
         },
         "pug-load": {
@@ -13553,8 +13552,8 @@
             "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
             "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
             "requires": {
-                "object-assign": "^4.1.0",
-                "pug-walk": "^1.1.8"
+                "object-assign": "4.1.1",
+                "pug-walk": "1.1.8"
             }
         },
         "pug-parser": {
@@ -13562,7 +13561,7 @@
             "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
             "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
             "requires": {
-                "pug-error": "^1.3.3",
+                "pug-error": "1.3.3",
                 "token-stream": "0.0.1"
             }
         },
@@ -13576,7 +13575,7 @@
             "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
             "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
             "requires": {
-                "pug-error": "^1.3.3"
+                "pug-error": "1.3.3"
             }
         },
         "pug-walk": {
@@ -13589,8 +13588,8 @@
             "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
             "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
             "requires": {
-                "end-of-stream": "^1.1.0",
-                "once": "^1.3.1"
+                "end-of-stream": "1.4.1",
+                "once": "1.4.0"
             }
         },
         "pumpify": {
@@ -13599,9 +13598,9 @@
             "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
             "dev": true,
             "requires": {
-                "duplexify": "^3.6.0",
-                "inherits": "^2.0.3",
-                "pump": "^2.0.0"
+                "duplexify": "3.7.1",
+                "inherits": "2.0.3",
+                "pump": "2.0.1"
             }
         },
         "punycode": {
@@ -13624,9 +13623,9 @@
             "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.1.tgz",
             "integrity": "sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q==",
             "requires": {
-                "decode-uri-component": "^0.2.0",
-                "split-on-first": "^1.0.0",
-                "strict-uri-encode": "^2.0.0"
+                "decode-uri-component": "0.2.0",
+                "split-on-first": "1.1.0",
+                "strict-uri-encode": "2.0.0"
             }
         },
         "querystring": {
@@ -13657,7 +13656,7 @@
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
             "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
             "requires": {
-                "safe-buffer": "^5.1.0"
+                "safe-buffer": "5.1.2"
             }
         },
         "randomfill": {
@@ -13665,8 +13664,8 @@
             "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
             "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
             "requires": {
-                "randombytes": "^2.0.5",
-                "safe-buffer": "^5.1.0"
+                "randombytes": "2.1.0",
+                "safe-buffer": "5.1.2"
             }
         },
         "range-parser": {
@@ -13690,8 +13689,8 @@
             "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz",
             "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==",
             "requires": {
-                "loader-utils": "^1.1.0",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -13699,9 +13698,9 @@
                     "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -13711,10 +13710,10 @@
             "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
             "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
             "requires": {
-                "deep-extend": "^0.6.0",
-                "ini": "~1.3.0",
-                "minimist": "^1.2.0",
-                "strip-json-comments": "~2.0.1"
+                "deep-extend": "0.6.0",
+                "ini": "1.3.5",
+                "minimist": "1.2.0",
+                "strip-json-comments": "2.0.1"
             },
             "dependencies": {
                 "minimist": {
@@ -13729,9 +13728,9 @@
             "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-1.9.0.tgz",
             "integrity": "sha512-Isas+egaK6qSk64jaEw4GgPStY4umYDbT7ZY93bZF1Af+b/JEsKsJdNOU2qG3WI0Z6tXo2DDq0kJCv8Yhu0zww==",
             "requires": {
-                "classnames": "^2.2.1",
-                "prop-types": "^15.5.6",
-                "react-lifecycles-compat": "^3.0.4"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "react": {
@@ -13739,10 +13738,10 @@
             "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz",
             "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1",
-                "prop-types": "^15.6.2",
-                "scheduler": "^0.13.6"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "prop-types": "15.7.2",
+                "scheduler": "0.13.6"
             }
         },
         "react-anime": {
@@ -13750,8 +13749,8 @@
             "resolved": "https://registry.npmjs.org/react-anime/-/react-anime-2.2.0.tgz",
             "integrity": "sha512-terZpZjLSanmxaPkb5mkIL1KSmMcF/4Unk5F1IfgoCTUkz6dRWcblA702X1NSsac/6oy60q2SyS857UcJCQPtQ==",
             "requires": {
-                "animejs": "^2.2.0",
-                "lodash.isequal": "^4.5.0"
+                "animejs": "2.2.0",
+                "lodash.isequal": "4.5.0"
             }
         },
         "react-autosuggest": {
@@ -13759,9 +13758,9 @@
             "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz",
             "integrity": "sha512-wFbp5QpgFQRfw9cwKvcgLR8theikOUkv8PFsuLYqI2PUgVlx186Cz8MYt5bLxculi+jxGGUUVt+h0esaBZZouw==",
             "requires": {
-                "prop-types": "^15.5.10",
-                "react-autowhatever": "^10.1.2",
-                "shallow-equal": "^1.0.0"
+                "prop-types": "15.7.2",
+                "react-autowhatever": "10.2.0",
+                "shallow-equal": "1.2.0"
             }
         },
         "react-autowhatever": {
@@ -13769,9 +13768,9 @@
             "resolved": "https://registry.npmjs.org/react-autowhatever/-/react-autowhatever-10.2.0.tgz",
             "integrity": "sha512-dqHH4uqiJldPMbL8hl/i2HV4E8FMTDEdVlOIbRqYnJi0kTpWseF9fJslk/KS9pGDnm80JkYzVI+nzFjnOG/u+g==",
             "requires": {
-                "prop-types": "^15.5.8",
-                "react-themeable": "^1.1.0",
-                "section-iterator": "^2.0.0"
+                "prop-types": "15.7.2",
+                "react-themeable": "1.1.0",
+                "section-iterator": "2.0.0"
             }
         },
         "react-bootstrap": {
@@ -13779,21 +13778,21 @@
             "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.9.tgz",
             "integrity": "sha512-M0BYLuuUdMITJ16+DDDb1p4vWV87csEBi/uOxZYODuDZh7hvbrJVahfvPXcqeqq4eEpNL+PKSlqb9fNaY0HZyA==",
             "requires": {
-                "@babel/runtime": "^7.4.2",
+                "@babel/runtime": "7.5.5",
                 "@react-bootstrap/react-popper": "1.2.1",
-                "@restart/context": "^2.1.4",
-                "@restart/hooks": "^0.3.0",
-                "classnames": "^2.2.6",
-                "dom-helpers": "^3.4.0",
-                "invariant": "^2.2.4",
-                "keycode": "^2.2.0",
-                "popper.js": "^1.14.7",
-                "prop-types": "^15.7.2",
-                "prop-types-extra": "^1.1.0",
-                "react-overlays": "^1.2.0",
-                "react-transition-group": "^4.0.0",
-                "uncontrollable": "^6.1.0",
-                "warning": "^4.0.3"
+                "@restart/context": "2.1.4",
+                "@restart/hooks": "0.3.8",
+                "classnames": "2.2.6",
+                "dom-helpers": "3.4.0",
+                "invariant": "2.2.4",
+                "keycode": "2.2.0",
+                "popper.js": "1.15.0",
+                "prop-types": "15.7.2",
+                "prop-types-extra": "1.1.0",
+                "react-overlays": "1.2.0",
+                "react-transition-group": "4.2.1",
+                "uncontrollable": "6.2.3",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "react-transition-group": {
@@ -13801,10 +13800,10 @@
                     "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.2.1.tgz",
                     "integrity": "sha512-IXrPr93VzCPupwm2O6n6C2kJIofJ/Rp5Ltihhm9UfE8lkuVX2ng/SUUl/oWjblybK9Fq2Io7LGa6maVqPB762Q==",
                     "requires": {
-                        "@babel/runtime": "^7.4.5",
-                        "dom-helpers": "^3.4.0",
-                        "loose-envify": "^1.4.0",
-                        "prop-types": "^15.6.2"
+                        "@babel/runtime": "7.5.5",
+                        "dom-helpers": "3.4.0",
+                        "loose-envify": "1.4.0",
+                        "prop-types": "15.7.2"
                     }
                 },
                 "uncontrollable": {
@@ -13812,8 +13811,8 @@
                     "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.2.3.tgz",
                     "integrity": "sha512-VgOAoBU2ptCL2bfTG2Mra0I8i1u6Aq84AFonD5tmCAYSfs3hWvr2Rlw0q2ntoxXTHjcQOmZOh3FKaN+UZVyREQ==",
                     "requires": {
-                        "@babel/runtime": "^7.4.5",
-                        "invariant": "^2.2.4"
+                        "@babel/runtime": "7.5.5",
+                        "invariant": "2.2.4"
                     }
                 },
                 "warning": {
@@ -13821,7 +13820,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13836,12 +13835,12 @@
             "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz",
             "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==",
             "requires": {
-                "@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"
+                "@icons/material": "0.2.4",
+                "lodash": "4.17.15",
+                "material-colors": "1.2.6",
+                "prop-types": "15.7.2",
+                "reactcss": "1.2.3",
+                "tinycolor2": "1.4.1"
             }
         },
         "react-context-toolbox": {
@@ -13854,7 +13853,7 @@
             "resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz",
             "integrity": "sha512-go5vMuGUxaB5PiTSIk+ZfAxLbHwcIgIfLhkBZ2SIMQjaCgnpttxa30z5ijEzfDjeOCTGRpxvkzcmE4Vt4Ppvyw==",
             "requires": {
-                "element-resize-event": "^2.0.4"
+                "element-resize-event": "2.0.9"
             }
         },
         "react-dom": {
@@ -13862,10 +13861,10 @@
             "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
             "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1",
-                "prop-types": "^15.6.2",
-                "scheduler": "^0.13.6"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "prop-types": "15.7.2",
+                "scheduler": "0.13.6"
             }
         },
         "react-golden-layout": {
@@ -13873,9 +13872,9 @@
             "resolved": "https://registry.npmjs.org/react-golden-layout/-/react-golden-layout-1.0.6.tgz",
             "integrity": "sha512-KZQ17Bnd+LfyCqe2scVMznrGKTciX3VwoT3y4xn3Qok9hknCvVXZfXe2RSX5zNG7FlLJzWt0VWqy8qZBHpQVuQ==",
             "requires": {
-                "golden-layout": "^1.5.9",
-                "react": "^16.3.0",
-                "react-dom": "^16.3.0"
+                "golden-layout": "1.5.9",
+                "react": "16.8.6",
+                "react-dom": "16.8.6"
             }
         },
         "react-image-lightbox-with-rotate": {
@@ -13883,9 +13882,9 @@
             "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==",
             "requires": {
-                "blueimp-load-image": "^2.19.0",
-                "prop-types": "^15.6.1",
-                "react-modal": "^3.4.4"
+                "blueimp-load-image": "2.24.0",
+                "prop-types": "15.7.2",
+                "react-modal": "3.9.1"
             }
         },
         "react-is": {
@@ -13898,7 +13897,7 @@
             "resolved": "https://registry.npmjs.org/react-jsx-parser/-/react-jsx-parser-1.19.1.tgz",
             "integrity": "sha512-ktc7P8v8dRSYtX5A06inci3dl4D6efGyJDqVSLQCEW0nCq5A+1gtKTcD7Wzmn84uY0eacM+zY15vN3ZQKUuQ1A==",
             "requires": {
-                "acorn-jsx": "^4.1.1"
+                "acorn-jsx": "4.1.1"
             }
         },
         "react-lifecycles-compat": {
@@ -13911,10 +13910,10 @@
             "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.3.0.tgz",
             "integrity": "sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A==",
             "requires": {
-                "@babel/runtime": "^7.2.0",
-                "get-node-dimensions": "^1.2.1",
-                "prop-types": "^15.6.2",
-                "resize-observer-polyfill": "^1.5.0"
+                "@babel/runtime": "7.5.5",
+                "get-node-dimensions": "1.2.1",
+                "prop-types": "15.7.2",
+                "resize-observer-polyfill": "1.5.1"
             }
         },
         "react-modal": {
@@ -13922,10 +13921,10 @@
             "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.9.1.tgz",
             "integrity": "sha512-k+TUkhGWpIVHLsEyjNmlyOYL0Uz03fNZvlkhCImd1h+6fhNgTi6H6jexVXPVhD2LMMDzJyfugxMN+APN/em+eQ==",
             "requires": {
-                "exenv": "^1.2.0",
-                "prop-types": "^15.5.10",
-                "react-lifecycles-compat": "^3.0.0",
-                "warning": "^4.0.3"
+                "exenv": "1.2.2",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "warning": {
@@ -13933,7 +13932,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13943,8 +13942,8 @@
             "resolved": "https://registry.npmjs.org/react-mosaic/-/react-mosaic-0.0.20.tgz",
             "integrity": "sha1-pSSr8uzyi5r2sh1NNQ/veCLvMJ4=",
             "requires": {
-                "prop-types": "^15.6.0",
-                "threads": "^0.8.0"
+                "prop-types": "15.7.2",
+                "threads": "0.8.1"
             }
         },
         "react-overlays": {
@@ -13952,14 +13951,14 @@
             "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-1.2.0.tgz",
             "integrity": "sha512-i/FCV8wR6aRaI+Kz/dpJhOdyx+ah2tN1RhT9InPrexyC4uzf3N4bNayFTGtUeQVacj57j1Mqh1CwV60/5153Iw==",
             "requires": {
-                "classnames": "^2.2.6",
-                "dom-helpers": "^3.4.0",
-                "prop-types": "^15.6.2",
-                "prop-types-extra": "^1.1.0",
-                "react-context-toolbox": "^2.0.2",
-                "react-popper": "^1.3.2",
-                "uncontrollable": "^6.0.0",
-                "warning": "^4.0.2"
+                "classnames": "2.2.6",
+                "dom-helpers": "3.4.0",
+                "prop-types": "15.7.2",
+                "prop-types-extra": "1.1.0",
+                "react-context-toolbox": "2.0.2",
+                "react-popper": "1.3.3",
+                "uncontrollable": "6.2.3",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "uncontrollable": {
@@ -13967,8 +13966,8 @@
                     "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-6.2.3.tgz",
                     "integrity": "sha512-VgOAoBU2ptCL2bfTG2Mra0I8i1u6Aq84AFonD5tmCAYSfs3hWvr2Rlw0q2ntoxXTHjcQOmZOh3FKaN+UZVyREQ==",
                     "requires": {
-                        "@babel/runtime": "^7.4.5",
-                        "invariant": "^2.2.4"
+                        "@babel/runtime": "7.5.5",
+                        "invariant": "2.2.4"
                     }
                 },
                 "warning": {
@@ -13976,7 +13975,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13986,12 +13985,12 @@
             "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz",
             "integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==",
             "requires": {
-                "@babel/runtime": "^7.1.2",
-                "create-react-context": "<=0.2.2",
-                "popper.js": "^1.14.4",
-                "prop-types": "^15.6.1",
-                "typed-styles": "^0.0.7",
-                "warning": "^4.0.2"
+                "@babel/runtime": "7.5.5",
+                "create-react-context": "0.2.2",
+                "popper.js": "1.15.0",
+                "prop-types": "15.7.2",
+                "typed-styles": "0.0.7",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "create-react-context": {
@@ -13999,8 +13998,8 @@
                     "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
                     "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
                     "requires": {
-                        "fbjs": "^0.8.0",
-                        "gud": "^1.0.0"
+                        "fbjs": "0.8.17",
+                        "gud": "1.0.0"
                     }
                 },
                 "typed-styles": {
@@ -14013,7 +14012,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -14023,8 +14022,8 @@
             "resolved": "https://registry.npmjs.org/react-simple-dropdown/-/react-simple-dropdown-3.2.3.tgz",
             "integrity": "sha512-NmyyvA0D4wph5ctzkn8U4wmblOacavJMl9gTOhQR3v8I997mc1FL1NFKkj3Mx+HNysBKRD/HI+kpxXCAgXumPw==",
             "requires": {
-                "classnames": "^2.1.2",
-                "prop-types": "^15.5.8"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2"
             }
         },
         "react-split-pane": {
@@ -14032,9 +14031,9 @@
             "resolved": "https://registry.npmjs.org/react-split-pane/-/react-split-pane-0.1.87.tgz",
             "integrity": "sha512-F22jqWyKB1WximT0U5HKdSuB9tmJGjjP+WUyveHxJJys3ANsljj163kCdsI6M3gdfyCVC+B2rq8sc5m2Ko02RA==",
             "requires": {
-                "prop-types": "^15.5.10",
-                "react-lifecycles-compat": "^3.0.4",
-                "react-style-proptype": "^3.0.0"
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4",
+                "react-style-proptype": "3.2.2"
             }
         },
         "react-style-proptype": {
@@ -14042,7 +14041,7 @@
             "resolved": "https://registry.npmjs.org/react-style-proptype/-/react-style-proptype-3.2.2.tgz",
             "integrity": "sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==",
             "requires": {
-                "prop-types": "^15.5.4"
+                "prop-types": "15.7.2"
             }
         },
         "react-table": {
@@ -14050,7 +14049,7 @@
             "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.10.3.tgz",
             "integrity": "sha512-sVlq2/rxVaQJywGD95+qGiMr/SMHFIFnXdx619BLOWE/Os5FOGtV6pQJNAjZixbQZiOu7dmBO1kME28uxh6wmA==",
             "requires": {
-                "classnames": "^2.2.5"
+                "classnames": "2.2.6"
             }
         },
         "react-themeable": {
@@ -14058,7 +14057,7 @@
             "resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
             "integrity": "sha1-fURm3ZsrX6dQWHJ4JenxUro3mg4=",
             "requires": {
-                "object-assign": "^3.0.0"
+                "object-assign": "3.0.0"
             },
             "dependencies": {
                 "object-assign": {
@@ -14073,10 +14072,10 @@
             "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
             "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
             "requires": {
-                "dom-helpers": "^3.4.0",
-                "loose-envify": "^1.4.0",
-                "prop-types": "^15.6.2",
-                "react-lifecycles-compat": "^3.0.4"
+                "dom-helpers": "3.4.0",
+                "loose-envify": "1.4.0",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "reactcss": {
@@ -14084,7 +14083,7 @@
             "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
             "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
             "requires": {
-                "lodash": "^4.0.1"
+                "lodash": "4.17.15"
             }
         },
         "read-pkg": {
@@ -14092,9 +14091,9 @@
             "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
             "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
             "requires": {
-                "load-json-file": "^1.0.0",
-                "normalize-package-data": "^2.3.2",
-                "path-type": "^1.0.0"
+                "load-json-file": "1.1.0",
+                "normalize-package-data": "2.5.0",
+                "path-type": "1.1.0"
             }
         },
         "read-pkg-up": {
@@ -14102,8 +14101,8 @@
             "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
             "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
             "requires": {
-                "find-up": "^1.0.0",
-                "read-pkg": "^1.0.0"
+                "find-up": "1.1.2",
+                "read-pkg": "1.1.0"
             },
             "dependencies": {
                 "find-up": {
@@ -14111,8 +14110,8 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
                     "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
                     "requires": {
-                        "path-exists": "^2.0.0",
-                        "pinkie-promise": "^2.0.0"
+                        "path-exists": "2.1.0",
+                        "pinkie-promise": "2.0.1"
                     }
                 },
                 "path-exists": {
@@ -14120,7 +14119,7 @@
                     "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
                     "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
                     "requires": {
-                        "pinkie-promise": "^2.0.0"
+                        "pinkie-promise": "2.0.1"
                     }
                 }
             }
@@ -14130,13 +14129,13 @@
             "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
             "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
+                "core-util-is": "1.0.2",
+                "inherits": "2.0.3",
+                "isarray": "1.0.0",
+                "process-nextick-args": "2.0.1",
+                "safe-buffer": "5.1.2",
+                "string_decoder": "1.1.1",
+                "util-deprecate": "1.0.2"
             }
         },
         "readdirp": {
@@ -14144,9 +14143,9 @@
             "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
             "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
             "requires": {
-                "graceful-fs": "^4.1.11",
-                "micromatch": "^3.1.10",
-                "readable-stream": "^2.0.2"
+                "graceful-fs": "4.2.0",
+                "micromatch": "3.1.10",
+                "readable-stream": "2.3.6"
             }
         },
         "readline": {
@@ -14160,9 +14159,9 @@
             "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=",
             "requires": {
                 "ast-types": "0.9.6",
-                "esprima": "~3.1.0",
-                "private": "~0.1.5",
-                "source-map": "~0.5.0"
+                "esprima": "3.1.3",
+                "private": "0.1.8",
+                "source-map": "0.5.7"
             },
             "dependencies": {
                 "esprima": {
@@ -14177,7 +14176,7 @@
             "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
             "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
             "requires": {
-                "resolve": "^1.1.6"
+                "resolve": "1.11.1"
             }
         },
         "redent": {
@@ -14185,8 +14184,8 @@
             "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
             "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
             "requires": {
-                "indent-string": "^2.1.0",
-                "strip-indent": "^1.0.1"
+                "indent-string": "2.1.0",
+                "strip-indent": "1.0.1"
             }
         },
         "reduce-flatten": {
@@ -14204,8 +14203,8 @@
             "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
             "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
             "requires": {
-                "extend-shallow": "^3.0.2",
-                "safe-regex": "^1.1.0"
+                "extend-shallow": "3.0.2",
+                "safe-regex": "1.1.0"
             }
         },
         "regexp-clone": {
@@ -14218,8 +14217,8 @@
             "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
             "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
             "requires": {
-                "rc": "^1.1.6",
-                "safe-buffer": "^5.0.1"
+                "rc": "1.2.8",
+                "safe-buffer": "5.1.2"
             }
         },
         "registry-url": {
@@ -14227,7 +14226,7 @@
             "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
             "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
             "requires": {
-                "rc": "^1.0.1"
+                "rc": "1.2.8"
             }
         },
         "remove-trailing-separator": {
@@ -14250,7 +14249,7 @@
             "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
             "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
             "requires": {
-                "is-finite": "^1.0.0"
+                "is-finite": "1.0.2"
             }
         },
         "request": {
@@ -14258,26 +14257,26 @@
             "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
             "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
             "requires": {
-                "aws-sign2": "~0.7.0",
-                "aws4": "^1.8.0",
-                "caseless": "~0.12.0",
-                "combined-stream": "~1.0.6",
-                "extend": "~3.0.2",
-                "forever-agent": "~0.6.1",
-                "form-data": "~2.3.2",
-                "har-validator": "~5.1.0",
-                "http-signature": "~1.2.0",
-                "is-typedarray": "~1.0.0",
-                "isstream": "~0.1.2",
-                "json-stringify-safe": "~5.0.1",
-                "mime-types": "~2.1.19",
-                "oauth-sign": "~0.9.0",
-                "performance-now": "^2.1.0",
-                "qs": "~6.5.2",
-                "safe-buffer": "^5.1.2",
-                "tough-cookie": "~2.4.3",
-                "tunnel-agent": "^0.6.0",
-                "uuid": "^3.3.2"
+                "aws-sign2": "0.7.0",
+                "aws4": "1.9.0",
+                "caseless": "0.12.0",
+                "combined-stream": "1.0.8",
+                "extend": "3.0.2",
+                "forever-agent": "0.6.1",
+                "form-data": "2.3.3",
+                "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.24",
+                "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"
             },
             "dependencies": {
                 "form-data": {
@@ -14285,9 +14284,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "qs": {
@@ -14302,10 +14301,10 @@
             "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.4.tgz",
             "integrity": "sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg==",
             "requires": {
-                "bluebird": "^3.5.0",
+                "bluebird": "3.5.5",
                 "request-promise-core": "1.1.2",
-                "stealthy-require": "^1.1.1",
-                "tough-cookie": "^2.3.3"
+                "stealthy-require": "1.1.1",
+                "tough-cookie": "2.4.3"
             }
         },
         "request-promise-core": {
@@ -14313,7 +14312,7 @@
             "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
             "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
             "requires": {
-                "lodash": "^4.17.11"
+                "lodash": "4.17.15"
             }
         },
         "request-promise-native": {
@@ -14323,8 +14322,8 @@
             "dev": true,
             "requires": {
                 "request-promise-core": "1.1.2",
-                "stealthy-require": "^1.1.1",
-                "tough-cookie": "^2.3.3"
+                "stealthy-require": "1.1.1",
+                "tough-cookie": "2.4.3"
             }
         },
         "require-directory": {
@@ -14342,8 +14341,8 @@
             "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
             "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
             "requires": {
-                "resolve-from": "^2.0.0",
-                "semver": "^5.1.0"
+                "resolve-from": "2.0.0",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "resolve-from": {
@@ -14369,7 +14368,7 @@
             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
             "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
             "requires": {
-                "path-parse": "^1.0.6"
+                "path-parse": "1.0.6"
             }
         },
         "resolve-cwd": {
@@ -14378,7 +14377,7 @@
             "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
             "dev": true,
             "requires": {
-                "resolve-from": "^3.0.0"
+                "resolve-from": "3.0.0"
             }
         },
         "resolve-dir": {
@@ -14387,8 +14386,8 @@
             "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
             "dev": true,
             "requires": {
-                "expand-tilde": "^2.0.0",
-                "global-modules": "^1.0.0"
+                "expand-tilde": "2.0.2",
+                "global-modules": "1.0.0"
             },
             "dependencies": {
                 "global-modules": {
@@ -14397,9 +14396,9 @@
                     "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
                     "dev": true,
                     "requires": {
-                        "global-prefix": "^1.0.1",
-                        "is-windows": "^1.0.1",
-                        "resolve-dir": "^1.0.0"
+                        "global-prefix": "1.0.2",
+                        "is-windows": "1.0.2",
+                        "resolve-dir": "1.0.1"
                     }
                 }
             }
@@ -14431,7 +14430,7 @@
             "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
             "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
             "requires": {
-                "align-text": "^0.1.1"
+                "align-text": "0.1.4"
             }
         },
         "rimraf": {
@@ -14439,7 +14438,7 @@
             "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
             "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
             "requires": {
-                "glob": "^7.1.3"
+                "glob": "7.1.4"
             }
         },
         "ripemd160": {
@@ -14447,8 +14446,8 @@
             "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
             "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
             "requires": {
-                "hash-base": "^3.0.0",
-                "inherits": "^2.0.1"
+                "hash-base": "3.0.4",
+                "inherits": "2.0.3"
             }
         },
         "rope-sequence": {
@@ -14462,7 +14461,7 @@
             "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1"
+                "aproba": "1.2.0"
             }
         },
         "safe-buffer": {
@@ -14475,7 +14474,7 @@
             "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
             "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "requires": {
-                "ret": "~0.1.10"
+                "ret": "0.1.15"
             }
         },
         "safer-buffer": {
@@ -14489,7 +14488,7 @@
             "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
             "optional": true,
             "requires": {
-                "sparse-bitfield": "^3.0.3"
+                "sparse-bitfield": "3.0.3"
             }
         },
         "sass-graph": {
@@ -14497,10 +14496,10 @@
             "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
             "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
             "requires": {
-                "glob": "^7.0.0",
-                "lodash": "^4.0.0",
-                "scss-tokenizer": "^0.2.3",
-                "yargs": "^7.0.0"
+                "glob": "7.1.4",
+                "lodash": "4.17.15",
+                "scss-tokenizer": "0.2.3",
+                "yargs": "7.1.0"
             }
         },
         "sass-loader": {
@@ -14509,12 +14508,12 @@
             "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==",
             "dev": true,
             "requires": {
-                "clone-deep": "^2.0.1",
-                "loader-utils": "^1.0.1",
-                "lodash.tail": "^4.1.1",
-                "neo-async": "^2.5.0",
-                "pify": "^3.0.0",
-                "semver": "^5.5.0"
+                "clone-deep": "2.0.2",
+                "loader-utils": "1.2.3",
+                "lodash.tail": "4.1.1",
+                "neo-async": "2.6.1",
+                "pify": "3.0.0",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "pify": {
@@ -14536,7 +14535,7 @@
             "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
             "dev": true,
             "requires": {
-                "xmlchars": "^2.1.1"
+                "xmlchars": "2.1.1"
             }
         },
         "scheduler": {
@@ -14544,8 +14543,8 @@
             "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz",
             "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1"
             }
         },
         "schema-utils": {
@@ -14553,8 +14552,8 @@
             "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
             "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
             "requires": {
-                "ajv": "^6.1.0",
-                "ajv-keywords": "^3.1.0"
+                "ajv": "6.10.2",
+                "ajv-keywords": "3.4.1"
             }
         },
         "scss-loader": {
@@ -14568,8 +14567,8 @@
             "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
             "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
             "requires": {
-                "js-base64": "^2.1.8",
-                "source-map": "^0.4.2"
+                "js-base64": "2.5.1",
+                "source-map": "0.4.4"
             },
             "dependencies": {
                 "source-map": {
@@ -14577,7 +14576,7 @@
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
                     "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
                     "requires": {
-                        "amdefine": ">=0.0.4"
+                        "amdefine": "1.0.1"
                     }
                 }
             }
@@ -14612,7 +14611,7 @@
             "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
             "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
             "requires": {
-                "semver": "^5.0.3"
+                "semver": "5.7.0"
             }
         },
         "send": {
@@ -14621,18 +14620,18 @@
             "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
             "requires": {
                 "debug": "2.6.9",
-                "depd": "~1.1.2",
-                "destroy": "~1.0.4",
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "etag": "~1.8.1",
+                "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",
+                "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"
+                "on-finished": "2.3.0",
+                "range-parser": "1.2.1",
+                "statuses": "1.5.0"
             },
             "dependencies": {
                 "ms": {
@@ -14659,13 +14658,13 @@
             "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
             "dev": true,
             "requires": {
-                "accepts": "~1.3.4",
+                "accepts": "1.3.7",
                 "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"
+                "escape-html": "1.0.3",
+                "http-errors": "1.6.3",
+                "mime-types": "2.1.24",
+                "parseurl": "1.3.3"
             },
             "dependencies": {
                 "http-errors": {
@@ -14674,10 +14673,10 @@
                     "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
                     "dev": true,
                     "requires": {
-                        "depd": "~1.1.2",
+                        "depd": "1.1.2",
                         "inherits": "2.0.3",
                         "setprototypeof": "1.1.0",
-                        "statuses": ">= 1.4.0 < 2"
+                        "statuses": "1.5.0"
                     }
                 },
                 "setprototypeof": {
@@ -14693,9 +14692,9 @@
             "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
             "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
             "requires": {
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "parseurl": "~1.3.3",
+                "encodeurl": "1.0.2",
+                "escape-html": "1.0.3",
+                "parseurl": "1.3.3",
                 "send": "0.17.1"
             }
         },
@@ -14709,10 +14708,10 @@
             "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
             "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
             "requires": {
-                "extend-shallow": "^2.0.1",
-                "is-extendable": "^0.1.1",
-                "is-plain-object": "^2.0.3",
-                "split-string": "^3.0.1"
+                "extend-shallow": "2.0.1",
+                "is-extendable": "0.1.1",
+                "is-plain-object": "2.0.4",
+                "split-string": "3.1.0"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -14720,7 +14719,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -14740,8 +14739,8 @@
             "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
             "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "shallow-clone": {
@@ -14750,9 +14749,9 @@
             "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
             "dev": true,
             "requires": {
-                "is-extendable": "^0.1.1",
-                "kind-of": "^5.0.0",
-                "mixin-object": "^2.0.1"
+                "is-extendable": "0.1.1",
+                "kind-of": "5.1.0",
+                "mixin-object": "2.0.1"
             },
             "dependencies": {
                 "kind-of": {
@@ -14773,16 +14772,16 @@
             "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.22.1.tgz",
             "integrity": "sha512-lXzSk/FL5b/MpWrT1pQZneKe25stVjEbl6uhhJcTULm7PhmJgKKRbTDM/vtjyUuC/RLqL2PRyC4rpKwbv3soEw==",
             "requires": {
-                "color": "^3.1.1",
-                "detect-libc": "^1.0.3",
-                "fs-copy-file-sync": "^1.1.1",
-                "nan": "^2.13.2",
-                "npmlog": "^4.1.2",
-                "prebuild-install": "^5.3.0",
-                "semver": "^6.0.0",
-                "simple-get": "^3.0.3",
-                "tar": "^4.4.8",
-                "tunnel-agent": "^0.6.0"
+                "color": "3.1.2",
+                "detect-libc": "1.0.3",
+                "fs-copy-file-sync": "1.1.1",
+                "nan": "2.14.0",
+                "npmlog": "4.1.2",
+                "prebuild-install": "5.3.0",
+                "semver": "6.2.0",
+                "simple-get": "3.0.3",
+                "tar": "4.4.10",
+                "tunnel-agent": "0.6.0"
             },
             "dependencies": {
                 "semver": {
@@ -14797,7 +14796,7 @@
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
             "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
             "requires": {
-                "shebang-regex": "^1.0.0"
+                "shebang-regex": "1.0.0"
             }
         },
         "shebang-regex": {
@@ -14815,9 +14814,9 @@
             "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
             "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==",
             "requires": {
-                "glob": "^7.0.0",
-                "interpret": "^1.0.0",
-                "rechoir": "^0.6.2"
+                "glob": "7.1.4",
+                "interpret": "1.2.0",
+                "rechoir": "0.6.2"
             }
         },
         "shellwords": {
@@ -14846,9 +14845,9 @@
             "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.3.tgz",
             "integrity": "sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==",
             "requires": {
-                "decompress-response": "^3.3.0",
-                "once": "^1.3.1",
-                "simple-concat": "^1.0.0"
+                "decompress-response": "3.3.0",
+                "once": "1.4.0",
+                "simple-concat": "1.0.0"
             }
         },
         "simple-swizzle": {
@@ -14856,7 +14855,7 @@
             "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
             "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
             "requires": {
-                "is-arrayish": "^0.3.1"
+                "is-arrayish": "0.3.2"
             },
             "dependencies": {
                 "is-arrayish": {
@@ -14882,14 +14881,14 @@
             "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
             "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
             "requires": {
-                "base": "^0.11.1",
-                "debug": "^2.2.0",
-                "define-property": "^0.2.5",
-                "extend-shallow": "^2.0.1",
-                "map-cache": "^0.2.2",
-                "source-map": "^0.5.6",
-                "source-map-resolve": "^0.5.0",
-                "use": "^3.1.0"
+                "base": "0.11.2",
+                "debug": "2.6.9",
+                "define-property": "0.2.5",
+                "extend-shallow": "2.0.1",
+                "map-cache": "0.2.2",
+                "source-map": "0.5.7",
+                "source-map-resolve": "0.5.2",
+                "use": "3.1.1"
             },
             "dependencies": {
                 "define-property": {
@@ -14897,7 +14896,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "extend-shallow": {
@@ -14905,7 +14904,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -14915,9 +14914,9 @@
             "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
             "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
             "requires": {
-                "define-property": "^1.0.0",
-                "isobject": "^3.0.0",
-                "snapdragon-util": "^3.0.1"
+                "define-property": "1.0.0",
+                "isobject": "3.0.1",
+                "snapdragon-util": "3.0.1"
             },
             "dependencies": {
                 "define-property": {
@@ -14925,7 +14924,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -14933,7 +14932,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -14941,7 +14940,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -14949,9 +14948,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -14961,7 +14960,7 @@
             "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
             "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
             "requires": {
-                "kind-of": "^3.2.0"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -14969,7 +14968,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -14979,12 +14978,12 @@
             "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz",
             "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==",
             "requires": {
-                "debug": "~4.1.0",
-                "engine.io": "~3.3.1",
-                "has-binary2": "~1.0.2",
-                "socket.io-adapter": "~1.1.0",
+                "debug": "4.1.1",
+                "engine.io": "3.3.2",
+                "has-binary2": "1.0.3",
+                "socket.io-adapter": "1.1.1",
                 "socket.io-client": "2.2.0",
-                "socket.io-parser": "~3.3.0"
+                "socket.io-parser": "3.3.0"
             },
             "dependencies": {
                 "debug": {
@@ -14992,7 +14991,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15016,15 +15015,15 @@
                 "base64-arraybuffer": "0.1.5",
                 "component-bind": "1.0.0",
                 "component-emitter": "1.2.1",
-                "debug": "~3.1.0",
-                "engine.io-client": "~3.3.1",
-                "has-binary2": "~1.0.2",
+                "debug": "3.1.0",
+                "engine.io-client": "3.3.2",
+                "has-binary2": "1.0.3",
                 "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",
+                "socket.io-parser": "3.3.0",
                 "to-array": "0.1.4"
             },
             "dependencies": {
@@ -15049,7 +15048,7 @@
             "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
             "requires": {
                 "component-emitter": "1.2.1",
-                "debug": "~3.1.0",
+                "debug": "3.1.0",
                 "isarray": "2.0.1"
             },
             "dependencies": {
@@ -15079,8 +15078,8 @@
             "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
             "dev": true,
             "requires": {
-                "faye-websocket": "^0.10.0",
-                "uuid": "^3.0.1"
+                "faye-websocket": "0.10.0",
+                "uuid": "3.3.2"
             }
         },
         "sockjs-client": {
@@ -15089,12 +15088,12 @@
             "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==",
             "dev": true,
             "requires": {
-                "debug": "^3.2.5",
-                "eventsource": "^1.0.7",
-                "faye-websocket": "~0.11.1",
-                "inherits": "^2.0.3",
-                "json3": "^3.3.2",
-                "url-parse": "^1.4.3"
+                "debug": "3.2.6",
+                "eventsource": "1.0.7",
+                "faye-websocket": "0.11.3",
+                "inherits": "2.0.3",
+                "json3": "3.3.3",
+                "url-parse": "1.4.7"
             },
             "dependencies": {
                 "debug": {
@@ -15103,7 +15102,7 @@
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "faye-websocket": {
@@ -15112,7 +15111,7 @@
                     "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
                     "dev": true,
                     "requires": {
-                        "websocket-driver": ">=0.5.1"
+                        "websocket-driver": "0.7.3"
                     }
                 },
                 "ms": {
@@ -15128,9 +15127,9 @@
             "resolved": "https://registry.npmjs.org/solr-node/-/solr-node-1.2.1.tgz",
             "integrity": "sha512-DN3+FSBgpJEgGTNddzS8tNb+ILSn5MLcsWf15G9rGxi/sROHbpcevdRSVx6s5/nz56c/5AnBTBZWak7IXWX97A==",
             "requires": {
-                "@log4js-node/log4js-api": "^1.0.2",
-                "node-fetch": "^2.3.0",
-                "underscore": "^1.8.3"
+                "@log4js-node/log4js-api": "1.0.2",
+                "node-fetch": "2.6.0",
+                "underscore": "1.9.1"
             },
             "dependencies": {
                 "node-fetch": {
@@ -15156,11 +15155,11 @@
             "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
             "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
             "requires": {
-                "atob": "^2.1.1",
-                "decode-uri-component": "^0.2.0",
-                "resolve-url": "^0.2.1",
-                "source-map-url": "^0.4.0",
-                "urix": "^0.1.0"
+                "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"
             }
         },
         "source-map-support": {
@@ -15168,8 +15167,8 @@
             "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
             "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
             "requires": {
-                "buffer-from": "^1.0.0",
-                "source-map": "^0.6.0"
+                "buffer-from": "1.1.1",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -15190,7 +15189,7 @@
             "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
             "optional": true,
             "requires": {
-                "memory-pager": "^1.0.2"
+                "memory-pager": "1.5.0"
             }
         },
         "spdx-correct": {
@@ -15198,8 +15197,8 @@
             "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
             "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
             "requires": {
-                "spdx-expression-parse": "^3.0.0",
-                "spdx-license-ids": "^3.0.0"
+                "spdx-expression-parse": "3.0.0",
+                "spdx-license-ids": "3.0.5"
             }
         },
         "spdx-exceptions": {
@@ -15212,8 +15211,8 @@
             "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
             "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
             "requires": {
-                "spdx-exceptions": "^2.1.0",
-                "spdx-license-ids": "^3.0.0"
+                "spdx-exceptions": "2.2.0",
+                "spdx-license-ids": "3.0.5"
             }
         },
         "spdx-license-ids": {
@@ -15227,11 +15226,11 @@
             "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==",
             "dev": true,
             "requires": {
-                "debug": "^4.1.0",
-                "handle-thing": "^2.0.0",
-                "http-deceiver": "^1.2.7",
-                "select-hose": "^2.0.0",
-                "spdy-transport": "^3.0.0"
+                "debug": "4.1.1",
+                "handle-thing": "2.0.0",
+                "http-deceiver": "1.2.7",
+                "select-hose": "2.0.0",
+                "spdy-transport": "3.0.0"
             },
             "dependencies": {
                 "debug": {
@@ -15240,7 +15239,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15257,12 +15256,12 @@
             "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
             "dev": true,
             "requires": {
-                "debug": "^4.1.0",
-                "detect-node": "^2.0.4",
-                "hpack.js": "^2.1.6",
-                "obuf": "^1.1.2",
-                "readable-stream": "^3.0.6",
-                "wbuf": "^1.7.3"
+                "debug": "4.1.1",
+                "detect-node": "2.0.4",
+                "hpack.js": "2.1.6",
+                "obuf": "1.1.2",
+                "readable-stream": "3.4.0",
+                "wbuf": "1.7.3"
             },
             "dependencies": {
                 "debug": {
@@ -15271,7 +15270,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15286,9 +15285,9 @@
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "dev": true,
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -15308,7 +15307,7 @@
             "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
             "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
             "requires": {
-                "extend-shallow": "^3.0.0"
+                "extend-shallow": "3.0.2"
             }
         },
         "sprintf-js": {
@@ -15321,15 +15320,15 @@
             "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
             "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
             "requires": {
-                "asn1": "~0.2.3",
-                "assert-plus": "^1.0.0",
-                "bcrypt-pbkdf": "^1.0.0",
-                "dashdash": "^1.12.0",
-                "ecc-jsbn": "~0.1.1",
-                "getpass": "^0.1.1",
-                "jsbn": "~0.1.0",
-                "safer-buffer": "^2.0.2",
-                "tweetnacl": "~0.14.0"
+                "asn1": "0.2.4",
+                "assert-plus": "1.0.0",
+                "bcrypt-pbkdf": "1.0.2",
+                "dashdash": "1.14.1",
+                "ecc-jsbn": "0.1.2",
+                "getpass": "0.1.7",
+                "jsbn": "0.1.1",
+                "safer-buffer": "2.1.2",
+                "tweetnacl": "0.14.5"
             },
             "dependencies": {
                 "assert-plus": {
@@ -15345,7 +15344,7 @@
             "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
             "dev": true,
             "requires": {
-                "safe-buffer": "^5.1.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "standard-error": {
@@ -15358,7 +15357,7 @@
             "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz",
             "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=",
             "requires": {
-                "standard-error": ">= 1.1.0 < 2"
+                "standard-error": "1.1.0"
             }
         },
         "static-extend": {
@@ -15366,8 +15365,8 @@
             "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
             "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
             "requires": {
-                "define-property": "^0.2.5",
-                "object-copy": "^0.1.0"
+                "define-property": "0.2.5",
+                "object-copy": "0.1.0"
             },
             "dependencies": {
                 "define-property": {
@@ -15375,7 +15374,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 }
             }
@@ -15390,7 +15389,7 @@
             "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
             "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
             "requires": {
-                "readable-stream": "^2.0.1"
+                "readable-stream": "2.3.6"
             }
         },
         "stealthy-require": {
@@ -15404,8 +15403,8 @@
             "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
             "dev": true,
             "requires": {
-                "inherits": "~2.0.1",
-                "readable-stream": "^2.0.2"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "stream-each": {
@@ -15414,8 +15413,8 @@
             "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
             "dev": true,
             "requires": {
-                "end-of-stream": "^1.1.0",
-                "stream-shift": "^1.0.0"
+                "end-of-stream": "1.4.1",
+                "stream-shift": "1.0.0"
             }
         },
         "stream-http": {
@@ -15424,11 +15423,11 @@
             "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
             "dev": true,
             "requires": {
-                "builtin-status-codes": "^3.0.0",
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.3.6",
-                "to-arraybuffer": "^1.0.0",
-                "xtend": "^4.0.0"
+                "builtin-status-codes": "3.0.0",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "to-arraybuffer": "1.0.1",
+                "xtend": "4.0.2"
             }
         },
         "stream-parser": {
@@ -15436,7 +15435,7 @@
             "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
             "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
             "requires": {
-                "debug": "2"
+                "debug": "2.6.9"
             }
         },
         "stream-shift": {
@@ -15455,9 +15454,9 @@
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
             "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
             "requires": {
-                "code-point-at": "^1.0.0",
-                "is-fullwidth-code-point": "^1.0.0",
-                "strip-ansi": "^3.0.0"
+                "code-point-at": "1.1.0",
+                "is-fullwidth-code-point": "1.0.0",
+                "strip-ansi": "3.0.1"
             }
         },
         "string.prototype.trimleft": {
@@ -15465,8 +15464,8 @@
             "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
             "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
             "requires": {
-                "define-properties": "^1.1.3",
-                "function-bind": "^1.1.1"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1"
             }
         },
         "string.prototype.trimright": {
@@ -15474,8 +15473,8 @@
             "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
             "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
             "requires": {
-                "define-properties": "^1.1.3",
-                "function-bind": "^1.1.1"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1"
             }
         },
         "string_decoder": {
@@ -15483,7 +15482,7 @@
             "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
             "requires": {
-                "safe-buffer": "~5.1.0"
+                "safe-buffer": "5.1.2"
             }
         },
         "stringify-parameters": {
@@ -15500,10 +15499,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -15513,7 +15512,7 @@
             "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
             "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
             "requires": {
-                "ansi-regex": "^2.0.0"
+                "ansi-regex": "2.1.1"
             }
         },
         "strip-bom": {
@@ -15521,7 +15520,7 @@
             "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
             "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
             "requires": {
-                "is-utf8": "^0.2.0"
+                "is-utf8": "0.2.1"
             }
         },
         "strip-eof": {
@@ -15534,7 +15533,7 @@
             "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
             "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
             "requires": {
-                "get-stdin": "^4.0.1"
+                "get-stdin": "4.0.1"
             },
             "dependencies": {
                 "get-stdin": {
@@ -15555,8 +15554,8 @@
             "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.1.0",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -15565,9 +15564,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -15588,11 +15587,11 @@
             "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
             "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
             "requires": {
-                "array-back": "^2.0.0",
-                "deep-extend": "~0.6.0",
-                "lodash.padend": "^4.6.1",
-                "typical": "^2.6.1",
-                "wordwrapjs": "^3.0.0"
+                "array-back": "2.0.0",
+                "deep-extend": "0.6.0",
+                "lodash.padend": "4.6.1",
+                "typical": "2.6.1",
+                "wordwrapjs": "3.0.0"
             }
         },
         "tapable": {
@@ -15606,13 +15605,13 @@
             "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
             "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
             "requires": {
-                "chownr": "^1.1.1",
-                "fs-minipass": "^1.2.5",
-                "minipass": "^2.3.5",
-                "minizlib": "^1.2.1",
-                "mkdirp": "^0.5.0",
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.3"
+                "chownr": "1.1.2",
+                "fs-minipass": "1.2.6",
+                "minipass": "2.3.5",
+                "minizlib": "1.2.1",
+                "mkdirp": "0.5.1",
+                "safe-buffer": "5.1.2",
+                "yallist": "3.0.3"
             }
         },
         "tar-fs": {
@@ -15620,10 +15619,10 @@
             "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
             "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
             "requires": {
-                "chownr": "^1.0.1",
-                "mkdirp": "^0.5.1",
-                "pump": "^1.0.0",
-                "tar-stream": "^1.1.2"
+                "chownr": "1.1.2",
+                "mkdirp": "0.5.1",
+                "pump": "1.0.3",
+                "tar-stream": "1.6.2"
             },
             "dependencies": {
                 "pump": {
@@ -15631,8 +15630,8 @@
                     "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
                     "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 }
             }
@@ -15642,13 +15641,13 @@
             "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
             "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
             "requires": {
-                "bl": "^1.0.0",
-                "buffer-alloc": "^1.2.0",
-                "end-of-stream": "^1.0.0",
-                "fs-constants": "^1.0.0",
-                "readable-stream": "^2.3.0",
-                "to-buffer": "^1.1.1",
-                "xtend": "^4.0.0"
+                "bl": "1.2.2",
+                "buffer-alloc": "1.2.0",
+                "end-of-stream": "1.4.1",
+                "fs-constants": "1.0.0",
+                "readable-stream": "2.3.6",
+                "to-buffer": "1.1.1",
+                "xtend": "4.0.2"
             }
         },
         "term-size": {
@@ -15656,7 +15655,7 @@
             "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
             "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
             "requires": {
-                "execa": "^0.7.0"
+                "execa": "0.7.0"
             }
         },
         "terser": {
@@ -15665,9 +15664,9 @@
             "integrity": "sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw==",
             "dev": true,
             "requires": {
-                "commander": "^2.20.0",
-                "source-map": "~0.6.1",
-                "source-map-support": "~0.5.12"
+                "commander": "2.20.0",
+                "source-map": "0.6.1",
+                "source-map-support": "0.5.12"
             },
             "dependencies": {
                 "source-map": {
@@ -15684,16 +15683,16 @@
             "integrity": "sha512-W2YWmxPjjkUcOWa4pBEv4OP4er1aeQJlSo2UhtCFQCuRXEHjOFscO8VyWHj9JLlA0RzQb8Y2/Ta78XZvT54uGg==",
             "dev": true,
             "requires": {
-                "cacache": "^11.3.2",
-                "find-cache-dir": "^2.0.0",
-                "is-wsl": "^1.1.0",
-                "loader-utils": "^1.2.3",
-                "schema-utils": "^1.0.0",
-                "serialize-javascript": "^1.7.0",
-                "source-map": "^0.6.1",
-                "terser": "^4.0.0",
-                "webpack-sources": "^1.3.0",
-                "worker-farm": "^1.7.0"
+                "cacache": "11.3.3",
+                "find-cache-dir": "2.1.0",
+                "is-wsl": "1.1.0",
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0",
+                "serialize-javascript": "1.7.0",
+                "source-map": "0.6.1",
+                "terser": "4.1.2",
+                "webpack-sources": "1.3.0",
+                "worker-farm": "1.7.0"
             },
             "dependencies": {
                 "cacache": {
@@ -15702,20 +15701,20 @@
                     "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==",
                     "dev": true,
                     "requires": {
-                        "bluebird": "^3.5.5",
-                        "chownr": "^1.1.1",
-                        "figgy-pudding": "^3.5.1",
-                        "glob": "^7.1.4",
-                        "graceful-fs": "^4.1.15",
-                        "lru-cache": "^5.1.1",
-                        "mississippi": "^3.0.0",
-                        "mkdirp": "^0.5.1",
-                        "move-concurrently": "^1.0.1",
-                        "promise-inflight": "^1.0.1",
-                        "rimraf": "^2.6.3",
-                        "ssri": "^6.0.1",
-                        "unique-filename": "^1.1.1",
-                        "y18n": "^4.0.0"
+                        "bluebird": "3.5.5",
+                        "chownr": "1.1.2",
+                        "figgy-pudding": "3.5.1",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.0",
+                        "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.7.1",
+                        "ssri": "6.0.1",
+                        "unique-filename": "1.1.1",
+                        "y18n": "4.0.0"
                     },
                     "dependencies": {
                         "rimraf": {
@@ -15724,7 +15723,7 @@
                             "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                             "dev": true,
                             "requires": {
-                                "glob": "^7.1.3"
+                                "glob": "7.1.4"
                             }
                         }
                     }
@@ -15735,9 +15734,9 @@
                     "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
                     "dev": true,
                     "requires": {
-                        "commondir": "^1.0.1",
-                        "make-dir": "^2.0.0",
-                        "pkg-dir": "^3.0.0"
+                        "commondir": "1.0.1",
+                        "make-dir": "2.1.0",
+                        "pkg-dir": "3.0.0"
                     }
                 },
                 "find-up": {
@@ -15746,7 +15745,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "locate-path": {
@@ -15755,8 +15754,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "lru-cache": {
@@ -15765,7 +15764,7 @@
                     "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
                     "dev": true,
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 },
                 "make-dir": {
@@ -15774,8 +15773,8 @@
                     "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
                     "dev": true,
                     "requires": {
-                        "pify": "^4.0.1",
-                        "semver": "^5.6.0"
+                        "pify": "4.0.1",
+                        "semver": "5.7.0"
                     }
                 },
                 "mississippi": {
@@ -15784,16 +15783,16 @@
                     "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
                     "dev": true,
                     "requires": {
-                        "concat-stream": "^1.5.0",
-                        "duplexify": "^3.4.2",
-                        "end-of-stream": "^1.1.0",
-                        "flush-write-stream": "^1.0.0",
-                        "from2": "^2.1.0",
-                        "parallel-transform": "^1.1.0",
-                        "pump": "^3.0.0",
-                        "pumpify": "^1.3.3",
-                        "stream-each": "^1.1.0",
-                        "through2": "^2.0.0"
+                        "concat-stream": "1.6.2",
+                        "duplexify": "3.7.1",
+                        "end-of-stream": "1.4.1",
+                        "flush-write-stream": "1.1.1",
+                        "from2": "2.3.0",
+                        "parallel-transform": "1.1.0",
+                        "pump": "3.0.0",
+                        "pumpify": "1.5.1",
+                        "stream-each": "1.2.3",
+                        "through2": "2.0.5"
                     }
                 },
                 "p-locate": {
@@ -15802,7 +15801,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "pify": {
@@ -15817,7 +15816,7 @@
                     "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
                     "dev": true,
                     "requires": {
-                        "find-up": "^3.0.0"
+                        "find-up": "3.0.0"
                     }
                 },
                 "pump": {
@@ -15826,8 +15825,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "schema-utils": {
@@ -15836,9 +15835,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 },
                 "source-map": {
@@ -15853,7 +15852,7 @@
                     "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
                     "dev": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1"
+                        "figgy-pudding": "3.5.1"
                     }
                 },
                 "y18n": {
@@ -15869,8 +15868,8 @@
             "resolved": "https://registry.npmjs.org/threads/-/threads-0.8.1.tgz",
             "integrity": "sha1-40ARW1lHMW0vfuMSPEwsW/nHbXI=",
             "requires": {
-                "eventemitter3": "^2.0.2",
-                "native-promise-only": "^0.8.1"
+                "eventemitter3": "2.0.3",
+                "native-promise-only": "0.8.1"
             }
         },
         "through": {
@@ -15884,8 +15883,8 @@
             "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
             "dev": true,
             "requires": {
-                "readable-stream": "~2.3.6",
-                "xtend": "~4.0.1"
+                "readable-stream": "2.3.6",
+                "xtend": "4.0.2"
             }
         },
         "thunky": {
@@ -15905,7 +15904,7 @@
             "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
             "dev": true,
             "requires": {
-                "setimmediate": "^1.0.4"
+                "setimmediate": "1.0.5"
             }
         },
         "tinycolor2": {
@@ -15939,7 +15938,7 @@
             "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
             "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -15947,7 +15946,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -15957,10 +15956,10 @@
             "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
             "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
             "requires": {
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "regex-not": "^1.0.2",
-                "safe-regex": "^1.1.0"
+                "define-property": "2.0.2",
+                "extend-shallow": "3.0.2",
+                "regex-not": "1.0.2",
+                "safe-regex": "1.1.0"
             }
         },
         "to-regex-range": {
@@ -15968,8 +15967,8 @@
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
             "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
             "requires": {
-                "is-number": "^3.0.0",
-                "repeat-string": "^1.6.1"
+                "is-number": "3.0.0",
+                "repeat-string": "1.6.1"
             }
         },
         "toidentifier": {
@@ -15987,7 +15986,7 @@
             "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
             "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
             "requires": {
-                "nopt": "~1.0.10"
+                "nopt": "1.0.10"
             },
             "dependencies": {
                 "nopt": {
@@ -15995,7 +15994,7 @@
                     "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
                     "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
                     "requires": {
-                        "abbrev": "1"
+                        "abbrev": "1.1.1"
                     }
                 }
             }
@@ -16005,8 +16004,8 @@
             "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
             "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
             "requires": {
-                "psl": "^1.1.24",
-                "punycode": "^1.4.1"
+                "psl": "1.2.0",
+                "punycode": "1.4.1"
             },
             "dependencies": {
                 "punycode": {
@@ -16022,7 +16021,7 @@
             "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
             "dev": true,
             "requires": {
-                "punycode": "^2.1.0"
+                "punycode": "2.1.1"
             }
         },
         "traverse-chain": {
@@ -16046,7 +16045,7 @@
             "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
             "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
             "requires": {
-                "glob": "^7.1.2"
+                "glob": "7.1.4"
             }
         },
         "ts-loader": {
@@ -16055,11 +16054,11 @@
             "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==",
             "dev": true,
             "requires": {
-                "chalk": "^2.3.0",
-                "enhanced-resolve": "^4.0.0",
-                "loader-utils": "^1.0.2",
-                "micromatch": "^3.1.4",
-                "semver": "^5.0.1"
+                "chalk": "2.4.2",
+                "enhanced-resolve": "4.1.0",
+                "loader-utils": "1.2.3",
+                "micromatch": "3.1.10",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16068,7 +16067,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16077,9 +16076,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -16088,7 +16087,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16099,14 +16098,14 @@
             "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
             "dev": true,
             "requires": {
-                "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"
+                "arrify": "1.0.1",
+                "buffer-from": "1.1.1",
+                "diff": "3.5.0",
+                "make-error": "1.3.5",
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "source-map-support": "0.5.12",
+                "yn": "2.0.0"
             },
             "dependencies": {
                 "diff": {
@@ -16129,18 +16128,18 @@
             "integrity": "sha512-78CptStf6oA5wKkRXQPEMBR5zowhnw2bvCETRMhkz2DsuussA56s6lKgUX4EiMMiPkyYdSm8jkJ875j4eo4nkQ==",
             "dev": true,
             "requires": {
-                "dateformat": "~1.0.4-1.2.3",
-                "dynamic-dedupe": "^0.3.0",
-                "filewatcher": "~3.0.0",
-                "minimist": "^1.1.3",
-                "mkdirp": "^0.5.1",
-                "node-notifier": "^5.4.0",
-                "resolve": "^1.0.0",
-                "rimraf": "^2.6.1",
-                "source-map-support": "^0.5.12",
-                "tree-kill": "^1.2.1",
-                "ts-node": "*",
-                "tsconfig": "^7.0.0"
+                "dateformat": "1.0.12",
+                "dynamic-dedupe": "0.3.0",
+                "filewatcher": "3.0.1",
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "node-notifier": "5.4.0",
+                "resolve": "1.11.1",
+                "rimraf": "2.7.1",
+                "source-map-support": "0.5.12",
+                "tree-kill": "1.2.1",
+                "ts-node": "7.0.1",
+                "tsconfig": "7.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -16155,7 +16154,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -16166,10 +16165,10 @@
             "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
             "dev": true,
             "requires": {
-                "@types/strip-bom": "^3.0.0",
+                "@types/strip-bom": "3.0.0",
                 "@types/strip-json-comments": "0.0.30",
-                "strip-bom": "^3.0.0",
-                "strip-json-comments": "^2.0.0"
+                "strip-bom": "3.0.0",
+                "strip-json-comments": "2.0.1"
             },
             "dependencies": {
                 "strip-bom": {
@@ -16192,19 +16191,19 @@
             "integrity": "sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w==",
             "dev": true,
             "requires": {
-                "@babel/code-frame": "^7.0.0",
-                "builtin-modules": "^1.1.1",
-                "chalk": "^2.3.0",
-                "commander": "^2.12.1",
-                "diff": "^3.2.0",
-                "glob": "^7.1.1",
-                "js-yaml": "^3.13.1",
-                "minimatch": "^3.0.4",
-                "mkdirp": "^0.5.1",
-                "resolve": "^1.3.2",
-                "semver": "^5.3.0",
-                "tslib": "^1.8.0",
-                "tsutils": "^2.29.0"
+                "@babel/code-frame": "7.5.5",
+                "builtin-modules": "1.1.1",
+                "chalk": "2.4.2",
+                "commander": "2.20.0",
+                "diff": "3.5.0",
+                "glob": "7.1.4",
+                "js-yaml": "3.13.1",
+                "minimatch": "3.0.4",
+                "mkdirp": "0.5.1",
+                "resolve": "1.11.1",
+                "semver": "5.7.0",
+                "tslib": "1.10.0",
+                "tsutils": "2.29.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16213,7 +16212,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16222,9 +16221,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "diff": {
@@ -16239,7 +16238,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16250,11 +16249,11 @@
             "integrity": "sha512-jBHNNppXut6SgZ7CsTBh+6oMwVum9n8azbmcYSeMlsABhWWoHwjq631vIFXef3VSd75cCdX3rc6kstsB7rSVVw==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.0.2",
-                "mkdirp": "^0.5.1",
-                "object-assign": "^4.1.1",
-                "rimraf": "^2.4.4",
-                "semver": "^5.3.0"
+                "loader-utils": "1.2.3",
+                "mkdirp": "0.5.1",
+                "object-assign": "4.1.1",
+                "rimraf": "2.7.1",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "rimraf": {
@@ -16263,7 +16262,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -16274,7 +16273,7 @@
             "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
             "dev": true,
             "requires": {
-                "tslib": "^1.8.1"
+                "tslib": "1.10.0"
             }
         },
         "tty-browserify": {
@@ -16288,7 +16287,7 @@
             "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
             "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
             "requires": {
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "tweetnacl": {
@@ -16308,7 +16307,7 @@
             "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
             "dev": true,
             "requires": {
-                "prelude-ls": "~1.1.2"
+                "prelude-ls": "1.1.2"
             }
         },
         "type-detect": {
@@ -16322,7 +16321,7 @@
             "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
             "requires": {
                 "media-typer": "0.3.0",
-                "mime-types": "~2.1.24"
+                "mime-types": "2.1.24"
             }
         },
         "typed-styles": {
@@ -16361,9 +16360,9 @@
             "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
             "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
             "requires": {
-                "source-map": "~0.5.1",
-                "uglify-to-browserify": "~1.0.0",
-                "yargs": "~3.10.0"
+                "source-map": "0.5.7",
+                "uglify-to-browserify": "1.0.2",
+                "yargs": "3.10.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -16376,8 +16375,8 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
                     "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
                     "requires": {
-                        "center-align": "^0.1.1",
-                        "right-align": "^0.1.1",
+                        "center-align": "0.1.3",
+                        "right-align": "0.1.3",
                         "wordwrap": "0.0.2"
                     }
                 },
@@ -16386,9 +16385,9 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
                     "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
                     "requires": {
-                        "camelcase": "^1.0.2",
-                        "cliui": "^2.1.0",
-                        "decamelize": "^1.0.0",
+                        "camelcase": "1.2.1",
+                        "cliui": "2.1.0",
+                        "decamelize": "1.2.0",
                         "window-size": "0.1.0"
                     }
                 }
@@ -16405,7 +16404,7 @@
             "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
             "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
             "requires": {
-                "random-bytes": "~1.0.0"
+                "random-bytes": "1.0.0"
             }
         },
         "uid2": {
@@ -16418,7 +16417,7 @@
             "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz",
             "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==",
             "requires": {
-                "invariant": "^2.2.4"
+                "invariant": "2.2.4"
             }
         },
         "undefsafe": {
@@ -16426,7 +16425,7 @@
             "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
             "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
             "requires": {
-                "debug": "^2.2.0"
+                "debug": "2.6.9"
             }
         },
         "underscore": {
@@ -16439,10 +16438,10 @@
             "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
             "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
             "requires": {
-                "arr-union": "^3.1.0",
-                "get-value": "^2.0.6",
-                "is-extendable": "^0.1.1",
-                "set-value": "^2.0.1"
+                "arr-union": "3.1.0",
+                "get-value": "2.0.6",
+                "is-extendable": "0.1.1",
+                "set-value": "2.0.1"
             }
         },
         "uniq": {
@@ -16457,7 +16456,7 @@
             "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
             "dev": true,
             "requires": {
-                "unique-slug": "^2.0.0"
+                "unique-slug": "2.0.2"
             }
         },
         "unique-slug": {
@@ -16466,7 +16465,7 @@
             "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
             "dev": true,
             "requires": {
-                "imurmurhash": "^0.1.4"
+                "imurmurhash": "0.1.4"
             }
         },
         "unique-string": {
@@ -16474,7 +16473,7 @@
             "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
             "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
             "requires": {
-                "crypto-random-string": "^1.0.0"
+                "crypto-random-string": "1.0.0"
             }
         },
         "unpack-string": {
@@ -16492,8 +16491,8 @@
             "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
             "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
             "requires": {
-                "has-value": "^0.3.1",
-                "isobject": "^3.0.0"
+                "has-value": "0.3.1",
+                "isobject": "3.0.1"
             },
             "dependencies": {
                 "has-value": {
@@ -16501,9 +16500,9 @@
                     "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
                     "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
                     "requires": {
-                        "get-value": "^2.0.3",
-                        "has-values": "^0.1.4",
-                        "isobject": "^2.0.0"
+                        "get-value": "2.0.6",
+                        "has-values": "0.1.4",
+                        "isobject": "2.1.0"
                     },
                     "dependencies": {
                         "isobject": {
@@ -16538,16 +16537,16 @@
             "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
             "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
             "requires": {
-                "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"
+                "boxen": "1.3.0",
+                "chalk": "2.4.2",
+                "configstore": "3.1.2",
+                "import-lazy": "2.1.0",
+                "is-ci": "1.2.1",
+                "is-installed-globally": "0.1.0",
+                "is-npm": "1.0.0",
+                "latest-version": "3.1.0",
+                "semver-diff": "2.1.0",
+                "xdg-basedir": "3.0.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16555,7 +16554,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16563,9 +16562,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -16573,7 +16572,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16583,7 +16582,7 @@
             "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
             "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
             "requires": {
-                "punycode": "^2.1.0"
+                "punycode": "2.1.1"
             }
         },
         "urix": {
@@ -16614,9 +16613,9 @@
             "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz",
             "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==",
             "requires": {
-                "loader-utils": "^1.1.0",
-                "mime": "^2.0.3",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "mime": "2.4.4",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "mime": {
@@ -16629,9 +16628,9 @@
                     "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -16642,8 +16641,8 @@
             "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
             "dev": true,
             "requires": {
-                "querystringify": "^2.1.1",
-                "requires-port": "^1.0.0"
+                "querystringify": "2.1.1",
+                "requires-port": "1.0.0"
             }
         },
         "url-parse-lax": {
@@ -16651,7 +16650,7 @@
             "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
             "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
             "requires": {
-                "prepend-http": "^1.0.1"
+                "prepend-http": "1.0.4"
             }
         },
         "url-template": {
@@ -16699,8 +16698,8 @@
             "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
             "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
             "requires": {
-                "spdx-correct": "^3.0.0",
-                "spdx-expression-parse": "^3.0.0"
+                "spdx-correct": "3.1.0",
+                "spdx-expression-parse": "3.0.0"
             }
         },
         "validator": {
@@ -16718,9 +16717,9 @@
             "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
             "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
             "requires": {
-                "assert-plus": "^1.0.0",
+                "assert-plus": "1.0.0",
                 "core-util-is": "1.0.2",
-                "extsprintf": "^1.2.0"
+                "extsprintf": "1.3.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -16747,7 +16746,7 @@
             "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
             "dev": true,
             "requires": {
-                "browser-process-hrtime": "^0.1.2"
+                "browser-process-hrtime": "0.1.3"
             }
         },
         "w3c-keyname": {
@@ -16761,9 +16760,9 @@
             "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
             "dev": true,
             "requires": {
-                "domexception": "^1.0.1",
-                "webidl-conversions": "^4.0.2",
-                "xml-name-validator": "^3.0.0"
+                "domexception": "1.0.1",
+                "webidl-conversions": "4.0.2",
+                "xml-name-validator": "3.0.0"
             }
         },
         "warning": {
@@ -16771,7 +16770,7 @@
             "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
             "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
             "requires": {
-                "loose-envify": "^1.0.0"
+                "loose-envify": "1.4.0"
             }
         },
         "watchpack": {
@@ -16780,9 +16779,9 @@
             "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
             "dev": true,
             "requires": {
-                "chokidar": "^2.0.2",
-                "graceful-fs": "^4.1.2",
-                "neo-async": "^2.5.0"
+                "chokidar": "2.1.6",
+                "graceful-fs": "4.2.0",
+                "neo-async": "2.6.1"
             }
         },
         "wbuf": {
@@ -16791,7 +16790,7 @@
             "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
             "dev": true,
             "requires": {
-                "minimalistic-assert": "^1.0.0"
+                "minimalistic-assert": "1.0.1"
             }
         },
         "webidl-conversions": {
@@ -16810,25 +16809,25 @@
                 "@webassemblyjs/helper-module-context": "1.8.5",
                 "@webassemblyjs/wasm-edit": "1.8.5",
                 "@webassemblyjs/wasm-parser": "1.8.5",
-                "acorn": "^6.2.0",
-                "ajv": "^6.1.0",
-                "ajv-keywords": "^3.1.0",
-                "chrome-trace-event": "^1.0.0",
-                "enhanced-resolve": "^4.1.0",
-                "eslint-scope": "^4.0.0",
-                "json-parse-better-errors": "^1.0.2",
-                "loader-runner": "^2.3.0",
-                "loader-utils": "^1.1.0",
-                "memory-fs": "~0.4.1",
-                "micromatch": "^3.1.8",
-                "mkdirp": "~0.5.0",
-                "neo-async": "^2.5.0",
-                "node-libs-browser": "^2.0.0",
-                "schema-utils": "^1.0.0",
-                "tapable": "^1.1.0",
-                "terser-webpack-plugin": "^1.1.0",
-                "watchpack": "^1.5.0",
-                "webpack-sources": "^1.3.0"
+                "acorn": "6.2.1",
+                "ajv": "6.10.2",
+                "ajv-keywords": "3.4.1",
+                "chrome-trace-event": "1.0.2",
+                "enhanced-resolve": "4.1.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.1",
+                "neo-async": "2.6.1",
+                "node-libs-browser": "2.2.1",
+                "schema-utils": "1.0.0",
+                "tapable": "1.1.3",
+                "terser-webpack-plugin": "1.3.0",
+                "watchpack": "1.6.0",
+                "webpack-sources": "1.3.0"
             },
             "dependencies": {
                 "acorn": {
@@ -16843,9 +16842,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -16881,7 +16880,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "camelcase": {
@@ -16896,9 +16895,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     },
                     "dependencies": {
                         "supports-color": {
@@ -16907,7 +16906,7 @@
                             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                             "dev": true,
                             "requires": {
-                                "has-flag": "^3.0.0"
+                                "has-flag": "3.0.0"
                             }
                         }
                     }
@@ -16918,9 +16917,9 @@
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "dev": true,
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "cross-spawn": {
@@ -16929,11 +16928,11 @@
                     "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
                     "dev": true,
                     "requires": {
-                        "nice-try": "^1.0.4",
-                        "path-key": "^2.0.1",
-                        "semver": "^5.5.0",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "nice-try": "1.0.5",
+                        "path-key": "2.0.1",
+                        "semver": "5.7.0",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     }
                 },
                 "execa": {
@@ -16942,13 +16941,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "find-up": {
@@ -16957,7 +16956,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-caller-file": {
@@ -16972,7 +16971,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -16993,7 +16992,7 @@
                     "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
                     "dev": true,
                     "requires": {
-                        "invert-kv": "^2.0.0"
+                        "invert-kv": "2.0.0"
                     }
                 },
                 "locate-path": {
@@ -17002,8 +17001,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "os-locale": {
@@ -17012,9 +17011,9 @@
                     "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
                     "dev": true,
                     "requires": {
-                        "execa": "^1.0.0",
-                        "lcid": "^2.0.0",
-                        "mem": "^4.0.0"
+                        "execa": "1.0.0",
+                        "lcid": "2.0.0",
+                        "mem": "4.3.0"
                     }
                 },
                 "p-locate": {
@@ -17023,7 +17022,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "pump": {
@@ -17032,8 +17031,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "require-main-filename": {
@@ -17048,9 +17047,9 @@
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "dev": true,
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -17059,7 +17058,7 @@
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "dev": true,
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "supports-color": {
@@ -17068,7 +17067,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "which-module": {
@@ -17083,9 +17082,9 @@
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -17100,17 +17099,17 @@
                     "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
                     "dev": true,
                     "requires": {
-                        "cliui": "^5.0.0",
-                        "find-up": "^3.0.0",
-                        "get-caller-file": "^2.0.1",
-                        "os-locale": "^3.1.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^2.0.0",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^3.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^4.0.0",
-                        "yargs-parser": "^13.1.0"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "os-locale": "3.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -17119,8 +17118,8 @@
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "dev": true,
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -17131,10 +17130,10 @@
             "integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==",
             "dev": true,
             "requires": {
-                "memory-fs": "^0.4.1",
-                "mime": "^2.4.2",
-                "range-parser": "^1.2.1",
-                "webpack-log": "^2.0.0"
+                "memory-fs": "0.4.1",
+                "mime": "2.4.4",
+                "range-parser": "1.2.1",
+                "webpack-log": "2.0.0"
             },
             "dependencies": {
                 "mime": {
@@ -17149,8 +17148,8 @@
                     "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
                     "dev": true,
                     "requires": {
-                        "ansi-colors": "^3.0.0",
-                        "uuid": "^3.3.2"
+                        "ansi-colors": "3.2.4",
+                        "uuid": "3.3.2"
                     }
                 }
             }
@@ -17162,35 +17161,35 @@
             "dev": true,
             "requires": {
                 "ansi-html": "0.0.7",
-                "bonjour": "^3.5.0",
-                "chokidar": "^2.1.6",
-                "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.2.1",
-                "http-proxy-middleware": "^0.19.1",
-                "import-local": "^2.0.0",
-                "internal-ip": "^4.3.0",
-                "ip": "^1.1.5",
-                "killable": "^1.0.1",
-                "loglevel": "^1.6.3",
-                "opn": "^5.5.0",
-                "p-retry": "^3.0.1",
-                "portfinder": "^1.0.20",
-                "schema-utils": "^1.0.0",
-                "selfsigned": "^1.10.4",
-                "semver": "^6.1.1",
-                "serve-index": "^1.9.1",
+                "bonjour": "3.5.0",
+                "chokidar": "2.1.6",
+                "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.2.1",
+                "http-proxy-middleware": "0.19.1",
+                "import-local": "2.0.0",
+                "internal-ip": "4.3.0",
+                "ip": "1.1.5",
+                "killable": "1.0.1",
+                "loglevel": "1.6.3",
+                "opn": "5.5.0",
+                "p-retry": "3.0.1",
+                "portfinder": "1.0.21",
+                "schema-utils": "1.0.0",
+                "selfsigned": "1.10.4",
+                "semver": "6.2.0",
+                "serve-index": "1.9.1",
                 "sockjs": "0.3.19",
                 "sockjs-client": "1.3.0",
-                "spdy": "^4.0.0",
-                "strip-ansi": "^3.0.1",
-                "supports-color": "^6.1.0",
-                "url": "^0.11.0",
-                "webpack-dev-middleware": "^3.7.0",
-                "webpack-log": "^2.0.0",
+                "spdy": "4.0.0",
+                "strip-ansi": "3.0.1",
+                "supports-color": "6.1.0",
+                "url": "0.11.0",
+                "webpack-dev-middleware": "3.7.0",
+                "webpack-log": "2.0.0",
                 "yargs": "12.0.5"
             },
             "dependencies": {
@@ -17212,9 +17211,9 @@
                     "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
                     "dev": true,
                     "requires": {
-                        "string-width": "^2.1.1",
-                        "strip-ansi": "^4.0.0",
-                        "wrap-ansi": "^2.0.0"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "4.0.0",
+                        "wrap-ansi": "2.1.0"
                     },
                     "dependencies": {
                         "strip-ansi": {
@@ -17223,7 +17222,7 @@
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "dev": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -17234,11 +17233,11 @@
                     "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
                     "dev": true,
                     "requires": {
-                        "nice-try": "^1.0.4",
-                        "path-key": "^2.0.1",
-                        "semver": "^5.5.0",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "nice-try": "1.0.5",
+                        "path-key": "2.0.1",
+                        "semver": "5.7.0",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "semver": {
@@ -17255,7 +17254,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "execa": {
@@ -17264,13 +17263,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "find-up": {
@@ -17279,7 +17278,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-stream": {
@@ -17288,7 +17287,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -17309,7 +17308,7 @@
                     "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
                     "dev": true,
                     "requires": {
-                        "invert-kv": "^2.0.0"
+                        "invert-kv": "2.0.0"
                     }
                 },
                 "locate-path": {
@@ -17318,8 +17317,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "ms": {
@@ -17334,9 +17333,9 @@
                     "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
                     "dev": true,
                     "requires": {
-                        "execa": "^1.0.0",
-                        "lcid": "^2.0.0",
-                        "mem": "^4.0.0"
+                        "execa": "1.0.0",
+                        "lcid": "2.0.0",
+                        "mem": "4.3.0"
                     }
                 },
                 "p-locate": {
@@ -17345,7 +17344,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "pump": {
@@ -17354,8 +17353,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "schema-utils": {
@@ -17364,9 +17363,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 },
                 "semver": {
@@ -17381,8 +17380,8 @@
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "dev": true,
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     },
                     "dependencies": {
                         "strip-ansi": {
@@ -17391,7 +17390,7 @@
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "dev": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -17402,7 +17401,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "webpack-log": {
@@ -17411,8 +17410,8 @@
                     "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
                     "dev": true,
                     "requires": {
-                        "ansi-colors": "^3.0.0",
-                        "uuid": "^3.3.2"
+                        "ansi-colors": "3.2.4",
+                        "uuid": "3.3.2"
                     }
                 },
                 "which-module": {
@@ -17427,18 +17426,18 @@
                     "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
                     "dev": true,
                     "requires": {
-                        "cliui": "^4.0.0",
-                        "decamelize": "^1.2.0",
-                        "find-up": "^3.0.0",
-                        "get-caller-file": "^1.0.1",
-                        "os-locale": "^3.0.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^1.0.1",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^2.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^3.2.1 || ^4.0.0",
-                        "yargs-parser": "^11.1.1"
+                        "cliui": "4.1.0",
+                        "decamelize": "1.2.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "1.0.3",
+                        "os-locale": "3.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "1.0.1",
+                        "set-blocking": "2.0.0",
+                        "string-width": "2.1.1",
+                        "which-module": "2.0.0",
+                        "y18n": "3.2.1",
+                        "yargs-parser": "11.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -17447,8 +17446,8 @@
                     "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
                     "dev": true,
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -17460,9 +17459,9 @@
             "dev": true,
             "requires": {
                 "ansi-html": "0.0.7",
-                "html-entities": "^1.2.0",
-                "querystring": "^0.2.0",
-                "strip-ansi": "^3.0.0"
+                "html-entities": "1.2.1",
+                "querystring": "0.2.0",
+                "strip-ansi": "3.0.1"
             }
         },
         "webpack-log": {
@@ -17471,10 +17470,10 @@
             "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==",
             "dev": true,
             "requires": {
-                "chalk": "^2.1.0",
-                "log-symbols": "^2.1.0",
-                "loglevelnext": "^1.0.1",
-                "uuid": "^3.1.0"
+                "chalk": "2.4.2",
+                "log-symbols": "2.2.0",
+                "loglevelnext": "1.0.5",
+                "uuid": "3.3.2"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -17483,7 +17482,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -17492,9 +17491,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -17503,7 +17502,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -17514,8 +17513,8 @@
             "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==",
             "dev": true,
             "requires": {
-                "source-list-map": "^2.0.0",
-                "source-map": "~0.6.1"
+                "source-list-map": "2.0.1",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -17532,9 +17531,9 @@
             "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
             "dev": true,
             "requires": {
-                "http-parser-js": ">=0.4.0 <0.4.11",
-                "safe-buffer": ">=5.1.0",
-                "websocket-extensions": ">=0.1.1"
+                "http-parser-js": "0.4.10",
+                "safe-buffer": "5.1.2",
+                "websocket-extensions": "0.1.3"
             }
         },
         "websocket-extensions": {
@@ -17569,9 +17568,9 @@
             "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
             "dev": true,
             "requires": {
-                "lodash.sortby": "^4.7.0",
-                "tr46": "^1.0.1",
-                "webidl-conversions": "^4.0.2"
+                "lodash.sortby": "4.7.0",
+                "tr46": "1.0.1",
+                "webidl-conversions": "4.0.2"
             }
         },
         "which": {
@@ -17579,7 +17578,7 @@
             "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
             "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
             "requires": {
-                "isexe": "^2.0.0"
+                "isexe": "2.0.0"
             }
         },
         "which-module": {
@@ -17597,7 +17596,7 @@
             "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
             "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
             "requires": {
-                "string-width": "^1.0.2 || 2"
+                "string-width": "1.0.2"
             }
         },
         "widest-line": {
@@ -17605,7 +17604,7 @@
             "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
             "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
             "requires": {
-                "string-width": "^2.1.1"
+                "string-width": "2.1.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -17623,8 +17622,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -17632,7 +17631,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -17642,8 +17641,8 @@
             "resolved": "https://registry.npmjs.org/wikijs/-/wikijs-6.0.1.tgz",
             "integrity": "sha512-67ZtXyVPspYM5/B5ci0NIwvPJyG23HPk33QQLgLbCcORQ6N0I3Mhxd/KsPRh3xyly87KDs/bh1xuIG6PVTCKGw==",
             "requires": {
-                "cheerio": "^1.0.0-rc.3",
-                "cross-fetch": "^3.0.2",
+                "cheerio": "1.0.0-rc.3",
+                "cross-fetch": "3.0.4",
                 "infobox-parser": "3.3.1"
             }
         },
@@ -17657,8 +17656,8 @@
             "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
             "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
             "requires": {
-                "acorn": "^3.1.0",
-                "acorn-globals": "^3.0.0"
+                "acorn": "3.3.0",
+                "acorn-globals": "3.1.0"
             },
             "dependencies": {
                 "acorn": {
@@ -17673,9 +17672,9 @@
             "resolved": "https://registry.npmjs.org/words-to-numbers/-/words-to-numbers-1.5.1.tgz",
             "integrity": "sha512-uvz7zSCKmmA7o5f5zp4Z5l24RQhy6HSNu10URhNxQWv1I82RsFaZX3qD07RLFUMJsCV38oAuaca13AvhO+9yGw==",
             "requires": {
-                "babel-runtime": "6.x.x",
-                "clj-fuzzy": "^0.3.2",
-                "its-set": "^1.1.5"
+                "babel-runtime": "6.26.0",
+                "clj-fuzzy": "0.3.3",
+                "its-set": "1.2.3"
             }
         },
         "wordwrap": {
@@ -17688,8 +17687,8 @@
             "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
             "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
             "requires": {
-                "reduce-flatten": "^1.0.1",
-                "typical": "^2.6.1"
+                "reduce-flatten": "1.0.1",
+                "typical": "2.6.1"
             }
         },
         "worker-farm": {
@@ -17698,7 +17697,7 @@
             "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
             "dev": true,
             "requires": {
-                "errno": "~0.1.7"
+                "errno": "0.1.7"
             }
         },
         "worker-loader": {
@@ -17706,8 +17705,8 @@
             "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
             "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
             "requires": {
-                "loader-utils": "^1.0.0",
-                "schema-utils": "^0.4.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "0.4.7"
             }
         },
         "worker-rpc": {
@@ -17716,7 +17715,7 @@
             "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==",
             "dev": true,
             "requires": {
-                "microevent.ts": "~0.1.1"
+                "microevent.ts": "0.1.1"
             }
         },
         "wrap-ansi": {
@@ -17724,8 +17723,8 @@
             "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
             "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
             "requires": {
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1"
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1"
             }
         },
         "wrappy": {
@@ -17738,9 +17737,9 @@
             "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
             "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
             "requires": {
-                "graceful-fs": "^4.1.11",
-                "imurmurhash": "^0.1.4",
-                "signal-exit": "^3.0.2"
+                "graceful-fs": "4.2.0",
+                "imurmurhash": "0.1.4",
+                "signal-exit": "3.0.2"
             }
         },
         "ws": {
@@ -17748,7 +17747,7 @@
             "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
             "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
             "requires": {
-                "async-limiter": "~1.0.0"
+                "async-limiter": "1.0.0"
             }
         },
         "xdg-basedir": {
@@ -17767,7 +17766,7 @@
             "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.1.9.tgz",
             "integrity": "sha1-wm/Qgm4Bor5xEHSKNPD4OFvkWfE=",
             "requires": {
-                "sax": ">=0.1.1"
+                "sax": "1.2.4"
             }
         },
         "xmlchars": {
@@ -17806,7 +17805,7 @@
             "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz",
             "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==",
             "requires": {
-                "@babel/runtime": "^7.6.3"
+                "@babel/runtime": "7.7.6"
             },
             "dependencies": {
                 "@babel/runtime": {
@@ -17814,7 +17813,7 @@
                     "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz",
                     "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==",
                     "requires": {
-                        "regenerator-runtime": "^0.13.2"
+                        "regenerator-runtime": "0.13.3"
                     }
                 }
             }
@@ -17824,19 +17823,19 @@
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
             "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
             "requires": {
-                "camelcase": "^3.0.0",
-                "cliui": "^3.2.0",
-                "decamelize": "^1.1.1",
-                "get-caller-file": "^1.0.1",
-                "os-locale": "^1.4.0",
-                "read-pkg-up": "^1.0.1",
-                "require-directory": "^2.1.1",
-                "require-main-filename": "^1.0.1",
-                "set-blocking": "^2.0.0",
-                "string-width": "^1.0.2",
-                "which-module": "^1.0.0",
-                "y18n": "^3.2.1",
-                "yargs-parser": "^5.0.0"
+                "camelcase": "3.0.0",
+                "cliui": "3.2.0",
+                "decamelize": "1.2.0",
+                "get-caller-file": "1.0.3",
+                "os-locale": "1.4.0",
+                "read-pkg-up": "1.0.1",
+                "require-directory": "2.1.1",
+                "require-main-filename": "1.0.1",
+                "set-blocking": "2.0.0",
+                "string-width": "1.0.2",
+                "which-module": "1.0.0",
+                "y18n": "3.2.1",
+                "yargs-parser": "5.0.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -17849,7 +17848,7 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
                     "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
                     "requires": {
-                        "camelcase": "^3.0.0"
+                        "camelcase": "3.0.0"
                     }
                 }
             }
@@ -17859,7 +17858,7 @@
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
             "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
             "requires": {
-                "camelcase": "^4.1.0"
+                "camelcase": "4.1.0"
             }
         },
         "yargs-unparser": {
@@ -17867,9 +17866,9 @@
             "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
             "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
             "requires": {
-                "flat": "^4.1.0",
-                "lodash": "^4.17.15",
-                "yargs": "^13.3.0"
+                "flat": "4.1.0",
+                "lodash": "4.17.15",
+                "yargs": "13.3.0"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -17882,7 +17881,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "camelcase": {
@@ -17895,9 +17894,9 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "find-up": {
@@ -17905,7 +17904,7 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-caller-file": {
@@ -17923,8 +17922,8 @@
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "p-locate": {
@@ -17932,7 +17931,7 @@
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.0"
                     }
                 },
                 "require-main-filename": {
@@ -17945,9 +17944,9 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -17955,7 +17954,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "which-module": {
@@ -17968,9 +17967,9 @@
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -17983,16 +17982,16 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
                     "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
                     "requires": {
-                        "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.1"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -18000,8 +17999,8 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -18050,9 +18049,9 @@
             "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.0.tgz",
             "integrity": "sha512-F/xoLqlQShgvn1BzHQCNiYIoo2R93GQIMH+tA6JC3ckMDkme4bnhEEXSferZcG5ea/6bZNx3GqSUHqT8TUO6uQ==",
             "requires": {
-                "archiver-utils": "^2.1.0",
-                "compress-commons": "^2.0.0",
-                "readable-stream": "^3.4.0"
+                "archiver-utils": "2.1.0",
+                "compress-commons": "2.0.0",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -18060,9 +18059,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
diff --git a/package.json b/package.json
index 9bd2273f8..a936182cc 100644
--- a/package.json
+++ b/package.json
@@ -176,7 +176,7 @@
         "nodemailer": "^5.1.1",
         "nodemon": "^1.18.10",
         "normalize.css": "^8.0.1",
-        "npm": "^6.13.4",
+        "npm": "^6.13.6",
         "p-limit": "^2.2.0",
         "passport": "^0.4.0",
         "passport-google-oauth20": "^2.0.0",
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 9e036d6c2..da0ad7efe 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -14,13 +14,13 @@ function makeTemplate(doc: Doc): boolean {
     const fieldKey = layout.replace("fieldKey={'", "").replace(/'}$/, "");
     const docs = DocListCast(layoutDoc[fieldKey]);
     let any = false;
-    docs.map(d => {
+    docs.forEach(d => {
         if (!StrCast(d.title).startsWith("-")) {
             any = true;
-            return Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc));
+            Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc));
+        } else if (d.type === DocumentType.COL) {
+            any = makeTemplate(d) || any;
         }
-        if (d.type === DocumentType.COL) return makeTemplate(d);
-        return false;
     });
     return any;
 }
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 10419ddb7..e56395ca1 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -146,7 +146,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
         templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout.chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
         return (
-            <Flyout anchorPoint={anchorPoints.RIGHT_TOP}
+            <Flyout anchorPoint={anchorPoints.LEFT_TOP}
                 content={<ul className="template-list" ref={this._dragRef} style={{ display: this._hidden ? "none" : "block" }}>
                     {templateMenu}
                     {<button onClick={this.clearTemplates}>Restore Defaults</button>}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index bb706e528..b466d9511 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -157,8 +157,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 whenActiveChanged={this.props.whenActiveChanged}
                 addDocTab={this.props.addDocTab}
                 pinToPres={this.props.pinToPres}
-                setPreviewScript={this.setPreviewScript}
-                previewScript={this.previewScript}
             />
         </div>;
     }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e71e11b48..c1e36272c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -187,9 +187,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             active={this.props.active}
             whenActiveChanged={this.props.whenActiveChanged}
             addDocTab={this.props.addDocTab}
-            pinToPres={this.props.pinToPres}
-            setPreviewScript={emptyFunction}
-            previewScript={undefined}>
+            pinToPres={this.props.pinToPres}>
         </ContentFittingDocumentView>;
     }
     getDocHeight(d?: Doc) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2b13d87ee..79fc477ab 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { Id } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { Document, listSpec } from '../../../new_fields/Schema';
 import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../new_fields/Types';
 import { emptyFunction, Utils, returnFalse, emptyPath } from '../../../Utils';
 import { Docs, DocUtils } from '../../documents/Documents';
 import { DocumentType } from "../../documents/DocumentTypes";
@@ -359,15 +359,24 @@ class TreeView extends React.Component<TreeViewProps> {
                     active={this.props.active}
                     whenActiveChanged={emptyFunction}
                     addDocTab={this.props.addDocTab}
-                    pinToPres={this.props.pinToPres}
-                    setPreviewScript={emptyFunction} />
+                    pinToPres={this.props.pinToPres} />
             </div>;
         }
     }
 
+    @action
+    bulletClick = (e: React.MouseEvent) => {
+        if (this.props.document.onClick) {
+            ScriptCast(this.props.document.onClick).script.run({ this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document }, console.log);
+        } else {
+            this.treeViewOpen = !this.treeViewOpen;
+        }
+        e.stopPropagation();
+    }
+
     @computed
     get renderBullet() {
-        return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
+        return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
             {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
         </div>;
     }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index a870b6043..184504e5a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -217,7 +217,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
             "true";
 
-        this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(fullScript, { doc: Doc.name });
+        const docFilter = StrCast(this.props.CollectionView.props.Document.docFilter);
+        const finalScript = docFilter && !fullScript.startsWith("(())") ? `${fullScript} ${docFilter ? "&&" : ""} (${docFilter})` :
+            docFilter ? docFilter : fullScript;
+
+        this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(finalScript, { doc: Doc.name });
     }
 
     @action
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 012115b1f..a965a6cc9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -44,7 +44,7 @@ function toLabel(target: FieldResult<Field>) {
     return String(target);
 }
 
-export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], viewDefsToJSX: (views: any) => ViewDefResult[]) {
+export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: any) => ViewDefResult[]) {
     const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 200);
     const pivotColumnGroups = new Map<FieldResult<Field>, Doc[]>();
 
@@ -57,9 +57,14 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
     }
 
     const minSize = Array.from(pivotColumnGroups.entries()).reduce((min, pair) => Math.min(min, pair[1].length), Infinity);
-    const numCols = NumCast(pivotDoc.pivotNumColumns, Math.ceil(Math.sqrt(minSize)));
+    let numCols = NumCast(pivotDoc.pivotNumColumns, Math.ceil(Math.sqrt(minSize)));
     const docMap = new Map<Doc, ViewDefBounds>();
     const groupNames: PivotData[] = [];
+    if (panelDim[0] < 2500) numCols = Math.min(5, numCols);
+    if (panelDim[0] < 2000) numCols = Math.min(4, numCols);
+    if (panelDim[0] < 1400) numCols = Math.min(3, numCols);
+    if (panelDim[0] < 1000) numCols = Math.min(2, numCols);
+    if (panelDim[0] < 600) numCols = 1;
 
     const expander = 1.05;
     const gap = .15;
@@ -85,14 +90,14 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
                 wid = layoutDoc.nativeHeight ? (NumCast(layoutDoc.nativeWidth) / NumCast(layoutDoc.nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
             }
             docMap.set(doc, {
-                x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2,
+                x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2 + (val.length < numCols ? (numCols - val.length) * pivotAxisWidth / 2 : 0),
                 y: -y,
                 width: wid,
                 height: hgt
             });
             xCount++;
             if (xCount >= numCols) {
-                xCount = (pivotAxisWidth - wid) / 2;
+                xCount = 0;
                 y += pivotAxisWidth * expander;
             }
         }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eb5a074bb..936c4413f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -772,7 +772,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     doPivotLayout(poolData: ObservableMap<string, any>) {
         return computePivotLayout(poolData, this.props.Document, this.childDocs,
-            this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), this.viewDefsToJSX);
+            this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), [this.props.PanelWidth(), this.props.PanelHeight()], this.viewDefsToJSX);
     }
 
     doFreeformLayout(poolData: ObservableMap<string, any>) {
@@ -987,6 +987,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             </CollectionFreeFormViewPannableContents>
         </MarqueeView>;
     }
+    @computed get contentScaling() {
+        let hscale = this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1;
+        let wscale = this.nativeWidth ? this.props.PanelWidth() / this.nativeWidth : 1;
+        return wscale < hscale ? wscale : hscale;
+    }
     render() {
         TraceMobx();
         // update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
@@ -998,9 +1003,17 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // otherwise, they are stored in fieldKey.  All annotations to this document are stored in the extension document
         if (!this.extensionDoc) return (null);
         // let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
-        return <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
-            style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
-            onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
+        return <div className={"collectionfreeformview-container"}
+            ref={this.createDropTarget}
+            onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+            onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}
+            style={{
+                pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+                transform: this.contentScaling ? `scale(${this.contentScaling})` : "",
+                transformOrigin: this.contentScaling ? "left top" : "",
+                width: this.contentScaling ? `${100 / this.contentScaling}%` : "",
+                height: this.contentScaling ? `${100 / this.contentScaling}%` : this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
+            }}>
             {!this.Document.LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 261a88deb..2e598a14d 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -103,6 +103,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 height: this.height,
                 zIndex: this.Document.zIndex || 0,
             }} >
+
             <DocumentView {...this.props}
                 dragDivName={"collectionFreeFormDocumentView-container"}
                 ContentScaling={this.contentScaling}
@@ -111,6 +112,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 PanelWidth={this.finalPanelWidth}
                 PanelHeight={this.finalPanelHeight}
             />
+            {/* <ContentFittingDocumentView {...this.props}
+                //dragDivName={"collectionFreeFormDocumentView-container"}
+                //ContentScaling={this.contentScaling}
+                getTransform={this.getTransform}
+                active={returnFalse}
+                focus={(doc: Doc) => this.props.focus(doc, false)}
+                // backgroundColor={this.clusterColorFunc}
+                PanelWidth={this.finalPanelWidth}
+                PanelHeight={this.finalPanelHeight}
+            /> */}
         </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 2f8142a44..bbec66233 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -39,8 +39,6 @@ interface ContentFittingDocumentViewProps {
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     dontRegisterView?: boolean;
-    setPreviewScript: (script: string) => void;
-    previewScript?: string;
 }
 
 @observer
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index 94755afec..863ea748b 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -106,8 +106,6 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
                 focus={this.props.focus}
                 active={this.props.active}
                 whenActiveChanged={this.props.whenActiveChanged}
-                setPreviewScript={emptyFunction}
-                previewScript={undefined}
             />}
         </div>;
     }
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index 5fd5d4ce1..f7a530790 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -183,7 +183,6 @@ export class FormattedTextBoxComment {
                                     moveDocument={returnFalse}
                                     getTransform={Transform.Identity}
                                     active={returnFalse}
-                                    setPreviewScript={returnEmptyString}
                                     addDocument={returnFalse}
                                     removeDocument={returnFalse}
                                     ruleProvider={undefined}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 37c837414..c02042380 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -180,7 +180,6 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
                     pinToPres={returnFalse}
                     PanelWidth={() => this.props.PanelWidth() - 20}
                     PanelHeight={() => 100}
-                    setPreviewScript={emptyFunction}
                     getTransform={Transform.Identity}
                     active={this.props.active}
                     moveDocument={this.props.moveDocument!}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 32ba5d19d..88a4d4c50 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -172,8 +172,6 @@ export class SearchItem extends React.Component<SearchItemProps> {
                     moveDocument={returnFalse}
                     active={returnFalse}
                     whenActiveChanged={returnFalse}
-                    setPreviewScript={emptyFunction}
-                    previewScript={undefined}
                 />
             </div>;
             return docview;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 8e0b28606..8117453e7 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -10,7 +10,7 @@ import { ObjectField } from "./ObjectField";
 import { PrefetchProxy, ProxyField } from "./Proxy";
 import { FieldId, RefField } from "./RefField";
 import { listSpec } from "./Schema";
-import { ComputedField } from "./ScriptField";
+import { ComputedField, ScriptField } from "./ScriptField";
 import { BoolCast, Cast, FieldValue, NumCast, PromiseValue, StrCast, ToConstructor } from "./Types";
 import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, updateFunction } from "./util";
 import { intersectRect } from "../Utils";
@@ -760,4 +760,10 @@ Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().SelectedDocs =
 Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
     const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)));
     return docs.length ? new List(docs) : prevValue;
+});
+Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, type: string, contains: boolean = true) {
+    const scriptText = `${contains ? "" : "!"}(((doc.${key} && (doc.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))) ||
+    ((doc.data_ext && doc.data_ext.${key}) && (doc.data_ext.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))))`;
+    container.docFilter = scriptText;
+    container.viewSpecScript = ScriptField.MakeFunction(scriptText, { doc: Doc.name });
 });
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 9955ff8c2de58cfe37e02d6a356b5a8a2930bb05 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Mon, 13 Jan 2020 13:29:18 -0500
Subject: fixed some scripting and added some functions for adding docFilters
 to collections

---
 package-lock.json                                  | 7019 ++++++++++----------
 src/client/views/ScriptBox.tsx                     |   13 +-
 .../views/collections/CollectionSchemaHeaders.tsx  |    5 +-
 .../views/collections/CollectionStackingView.tsx   |    6 -
 .../views/collections/CollectionTreeView.tsx       |   19 +-
 src/client/views/collections/CollectionView.tsx    |    6 +
 .../views/collections/CollectionViewChromes.tsx    |    7 +-
 src/client/views/nodes/DocumentView.tsx            |    8 +-
 src/new_fields/Doc.ts                              |   45 +-
 9 files changed, 3572 insertions(+), 3556 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/package-lock.json b/package-lock.json
index 3b4fbcc29..5d34e5edf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
             "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
             "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
             "requires": {
-                "@babel/highlight": "^7.0.0"
+                "@babel/highlight": "7.5.0"
             }
         },
         "@babel/helper-module-imports": {
@@ -17,7 +17,7 @@
             "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.7.4.tgz",
             "integrity": "sha512-dGcrX6K9l8258WFjyDLJwuVKxR4XZfU0/vTUgOQYWEnRD8mgr+p4d6fCUMq/ys0h4CCt/S5JhbvtyErjWouAUQ==",
             "requires": {
-                "@babel/types": "^7.7.4"
+                "@babel/types": "7.7.4"
             }
         },
         "@babel/highlight": {
@@ -25,9 +25,9 @@
             "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
             "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
             "requires": {
-                "chalk": "^2.0.0",
-                "esutils": "^2.0.2",
-                "js-tokens": "^4.0.0"
+                "chalk": "2.4.2",
+                "esutils": "2.0.2",
+                "js-tokens": "4.0.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -35,7 +35,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -43,9 +43,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -53,7 +53,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -63,7 +63,7 @@
             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz",
             "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==",
             "requires": {
-                "regenerator-runtime": "^0.13.2"
+                "regenerator-runtime": "0.13.3"
             }
         },
         "@babel/types": {
@@ -71,9 +71,9 @@
             "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz",
             "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==",
             "requires": {
-                "esutils": "^2.0.2",
-                "lodash": "^4.17.13",
-                "to-fast-properties": "^2.0.0"
+                "esutils": "2.0.2",
+                "lodash": "4.17.15",
+                "to-fast-properties": "2.0.0"
             }
         },
         "@emotion/cache": {
@@ -106,7 +106,7 @@
                 "@emotion/memoize": "0.7.3",
                 "@emotion/unitless": "0.7.4",
                 "@emotion/utils": "0.11.2",
-                "csstype": "^2.5.7"
+                "csstype": "2.6.6"
             }
         },
         "@emotion/sheet": {
@@ -144,7 +144,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-solid/-/fontawesome-free-solid-5.0.13.tgz",
             "integrity": "sha512-b+krVnqkdDt52Yfev0x0ZZgtxBQsLw00Zfa3uaVWIDzpNZVtrEXuxldUSUaN/ihgGhSNi8VpvDAdNPVgCKOSxw==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.1.7"
+                "@fortawesome/fontawesome-common-types": "0.1.7"
             }
         },
         "@fortawesome/fontawesome-svg-core": {
@@ -152,7 +152,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.26.tgz",
             "integrity": "sha512-3Dfd/v2IztP1TxKOxZiB5+4kaOZK9mNy0KU1vVK7nFlPWz3gzxrCWB+AloQhQUoJ8HhGqbzjliK89Vl7PExGbw==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.26"
+                "@fortawesome/fontawesome-common-types": "0.2.26"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -167,7 +167,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.12.0.tgz",
             "integrity": "sha512-50uCFzVUki3wfmFmrMNLFhOt8dP6YZ53zwR4dK9FR7Lwq1IVHXnSBb8MtGLe3urLJ2sA+CSu7Pc7s3i6/zLxmA==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.26"
+                "@fortawesome/fontawesome-common-types": "0.2.26"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -182,7 +182,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-5.12.0.tgz",
             "integrity": "sha512-FAvpmylTs0PosHwHrWPQX6/7ODc9M11kCE6AOAujFufDYzqTj2cPHT4yJO7zTEkKdAbbusJzbWpnOboMuyjeQA==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.26"
+                "@fortawesome/fontawesome-common-types": "0.2.26"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -197,7 +197,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.12.0.tgz",
             "integrity": "sha512-CnpsWs6GhTs9ekNB3d8rcO5HYqRkXbYKf2YNiAlTWbj5eVlPqsd/XH1F9If8jkcR1aegryAbln/qYeKVZzpM0g==",
             "requires": {
-                "@fortawesome/fontawesome-common-types": "^0.2.26"
+                "@fortawesome/fontawesome-common-types": "0.2.26"
             },
             "dependencies": {
                 "@fortawesome/fontawesome-common-types": {
@@ -212,7 +212,7 @@
             "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.8.tgz",
             "integrity": "sha512-I5h9YQg/ePA3Br9ISS18fcwOYmzQYDSM1ftH03/8nHkiqIVHtUyQBw482+60dnzvlr82gHt3mGm+nDUp159FCw==",
             "requires": {
-                "prop-types": "^15.5.10"
+                "prop-types": "15.7.2"
             }
         },
         "@hig/flyout": {
@@ -220,10 +220,10 @@
             "resolved": "https://registry.npmjs.org/@hig/flyout/-/flyout-1.2.0.tgz",
             "integrity": "sha512-/maJI6COH1UyUX3LCa0muG2VmPiXBtacyz8RAdLLcDIgeTpmyvxpb0FFZI/ib2HUbO2iILBN7qnXiMJ4YNJ/bQ==",
             "requires": {
-                "@hig/utils": "^0.4.0",
-                "emotion": "^10.0.0",
-                "prop-types": "^15.7.1",
-                "react-transition-group": "^2.3.1"
+                "@hig/utils": "0.4.0",
+                "emotion": "10.0.23",
+                "prop-types": "15.7.2",
+                "react-transition-group": "2.9.0"
             }
         },
         "@hig/theme-context": {
@@ -231,8 +231,8 @@
             "resolved": "https://registry.npmjs.org/@hig/theme-context/-/theme-context-2.1.3.tgz",
             "integrity": "sha512-c0Ju+Z8C532ZZtjwOLzN+XeO+pL3kqUawu6ZG3J084MH5RM9W8JCKyMf4D9Qr38jFWoiX6u8yiSxxjV/mz9Sqw==",
             "requires": {
-                "create-react-context": "^0.2.3",
-                "prop-types": "^15.6.1"
+                "create-react-context": "0.2.3",
+                "prop-types": "15.7.2"
             }
         },
         "@hig/theme-data": {
@@ -240,7 +240,7 @@
             "resolved": "https://registry.npmjs.org/@hig/theme-data/-/theme-data-2.13.0.tgz",
             "integrity": "sha512-ZU6GWRdVpU1baeDb4F/1BGzdVkdamFSrr+1DuRpwD4TbhFa5nXTT+xfyX20ZUf3eO5KP68QSAKFMaMPYbfEGQA==",
             "requires": {
-                "tinycolor2": "^1.4.1"
+                "tinycolor2": "1.4.1"
             }
         },
         "@hig/utils": {
@@ -248,8 +248,8 @@
             "resolved": "https://registry.npmjs.org/@hig/utils/-/utils-0.4.0.tgz",
             "integrity": "sha512-EQnMGZKdPh9UJaBUKLKXp92sSoCo+PTpgrGNd8q+71uRFdD0udMu/+yeVekTEtNOJcCk1gnKfyg1rRvIbTcpRw==",
             "requires": {
-                "emotion": "^10.0.0",
-                "lodash.memoize": "^4.1.2"
+                "emotion": "10.0.23",
+                "lodash.memoize": "4.1.2"
             }
         },
         "@icons/material": {
@@ -277,8 +277,8 @@
             "resolved": "https://registry.npmjs.org/@trendmicro/react-buttons/-/react-buttons-1.3.1.tgz",
             "integrity": "sha512-9zvt/fdkqCb9kxUdZnvTZKmbmykM2wDQ3VEJFtztGcKAkm4Wkq4oZOQLJXKfUQ1vX3w+YDJob18LkNOzaHI1UQ==",
             "requires": {
-                "classnames": "^2.2.5",
-                "prop-types": "^15.5.8"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2"
             }
         },
         "@trendmicro/react-dropdown": {
@@ -286,13 +286,13 @@
             "resolved": "https://registry.npmjs.org/@trendmicro/react-dropdown/-/react-dropdown-1.3.0.tgz",
             "integrity": "sha512-KwL0ksEZPay7qNsiGcPQ3aGmyfJCcUuIjiD9HZs6L66ScwSRoFkDlAjMTlRVLFcYVNhpuyUH4pPiFlKQQzDHGQ==",
             "requires": {
-                "@trendmicro/react-buttons": "^1.3.0",
-                "chained-function": "^0.5.0",
-                "classnames": "^2.2.5",
-                "dom-helpers": "^3.3.1",
-                "prop-types": "^15.6.0",
-                "uncontrollable": "^5.0.0",
-                "warning": "^3.0.0"
+                "@trendmicro/react-buttons": "1.3.1",
+                "chained-function": "0.5.0",
+                "classnames": "2.2.6",
+                "dom-helpers": "3.4.0",
+                "prop-types": "15.7.2",
+                "uncontrollable": "5.1.0",
+                "warning": "3.0.0"
             }
         },
         "@types/adm-zip": {
@@ -300,7 +300,7 @@
             "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.32.tgz",
             "integrity": "sha512-hv1O7ySn+XvP5OeDQcJFWwVb2v+GFGO1A9aMTQ5B/bzxb7WW21O8iRhVdsKKr8QwuiagzGmPP+gsUAYZ6bRddQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/animejs": {
@@ -318,7 +318,7 @@
             "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-3.0.0.tgz",
             "integrity": "sha512-orghAMOF+//wSg4ru2znk6jt0eIPvKTtMVLH7XcYcjbcRyAXRClDlh27QVdqnAvVM37yu9xDP6Nh7egRhNr8tQ==",
             "requires": {
-                "@types/glob": "*"
+                "@types/glob": "7.1.1"
             }
         },
         "@types/async": {
@@ -336,7 +336,7 @@
             "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.5.tgz",
             "integrity": "sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==",
             "requires": {
-                "@types/babel-types": "*"
+                "@types/babel-types": "7.0.7"
             }
         },
         "@types/bcrypt-nodejs": {
@@ -354,8 +354,8 @@
             "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz",
             "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==",
             "requires": {
-                "@types/connect": "*",
-                "@types/node": "*"
+                "@types/connect": "3.4.32",
+                "@types/node": "10.17.13"
             }
         },
         "@types/bson": {
@@ -363,7 +363,7 @@
             "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.1.tgz",
             "integrity": "sha512-K6VAEdLVJFBxKp8m5cRTbUfeZpuSvOuLKJLrgw9ANIXo00RiyGzgH4BKWWR4F520gV4tWmxG7q9sKQRVDuzrBw==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/caseless": {
@@ -386,7 +386,7 @@
             "resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.1.tgz",
             "integrity": "sha512-oeUWVaAwI+xINDUx+3F2vJkl/vVB03VChFF/Gl3iQCdbcakjuoJyMOba+3BXRtnBhxZ7uBYqQBi9EpLnvSoztA==",
             "requires": {
-                "@types/color-convert": "*"
+                "@types/color-convert": "1.9.0"
             }
         },
         "@types/color-convert": {
@@ -394,7 +394,7 @@
             "resolved": "https://registry.npmjs.org/@types/color-convert/-/color-convert-1.9.0.tgz",
             "integrity": "sha512-OKGEfULrvSL2VRbkl/gnjjgbbF7ycIlpSsX7Nkab4MOWi5XxmgBYvuiQ7lcCFY5cPDz7MUNaKgxte2VRmtr4Fg==",
             "requires": {
-                "@types/color-name": "*"
+                "@types/color-name": "1.1.1"
             }
         },
         "@types/color-name": {
@@ -407,7 +407,7 @@
             "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz",
             "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/connect-flash": {
@@ -415,7 +415,7 @@
             "resolved": "https://registry.npmjs.org/@types/connect-flash/-/connect-flash-0.0.34.tgz",
             "integrity": "sha512-QC93TwnTZ0sk//bfT81o7U4GOedbOZAcgvqi0v1vJqCESC8tqIVnhzB1CHiAUBUWFjoxG5JQF0TYaNa6DMb6Ig==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.2"
             }
         },
         "@types/cookie-parser": {
@@ -423,7 +423,7 @@
             "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.2.tgz",
             "integrity": "sha512-uwcY8m6SDQqciHsqcKDGbo10GdasYsPCYkH3hVegj9qAah6pX5HivOnOuI3WYmyQMnOATV39zv/Ybs0bC/6iVg==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.2"
             }
         },
         "@types/cookie-session": {
@@ -431,8 +431,8 @@
             "resolved": "https://registry.npmjs.org/@types/cookie-session/-/cookie-session-2.0.37.tgz",
             "integrity": "sha512-h8uZLDGyfAgER6kHbHlYWm1g/P/7zCBMOW6yT5/fQydVJxByJD4tohSvHBzJrGoLVmQJefQdfwuNkKb23cq29Q==",
             "requires": {
-                "@types/express": "*",
-                "@types/keygrip": "*"
+                "@types/express": "4.17.2",
+                "@types/keygrip": "1.0.1"
             }
         },
         "@types/d3-format": {
@@ -445,7 +445,7 @@
             "resolved": "https://registry.npmjs.org/@types/dotenv/-/dotenv-6.1.1.tgz",
             "integrity": "sha512-ftQl3DtBvqHl9L16tpqqzA4YzCSXZfi7g8cQceTz5rOlYtk/IZbFjAv3mLOQlNIgOaylCQWQoBdDQHPgEBJPHg==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/events": {
@@ -458,7 +458,7 @@
             "resolved": "https://registry.npmjs.org/@types/exif/-/exif-0.6.0.tgz",
             "integrity": "sha512-TyXIoevHn10FjPnCbNfpFlgb44c5KPsCbdWaNf59T76fKOl6YWfBQTmlt84kI7GtY4VuG9aW0qlEEmMuNDldoQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/express": {
@@ -466,9 +466,9 @@
             "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz",
             "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==",
             "requires": {
-                "@types/body-parser": "*",
-                "@types/express-serve-static-core": "*",
-                "@types/serve-static": "*"
+                "@types/body-parser": "1.17.1",
+                "@types/express-serve-static-core": "4.17.1",
+                "@types/serve-static": "1.13.3"
             }
         },
         "@types/express-flash": {
@@ -476,8 +476,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-flash/-/express-flash-0.0.0.tgz",
             "integrity": "sha512-zs1xXRIZOjghUBriJPSnhPmfDpqf/EQxT21ggi/9XZ9/RHYrUi+5vK2jnQrP2pD1abbuZvm7owLICiNCLBQzEQ==",
             "requires": {
-                "@types/connect-flash": "*",
-                "@types/express": "*"
+                "@types/connect-flash": "0.0.34",
+                "@types/express": "4.17.2"
             }
         },
         "@types/express-serve-static-core": {
@@ -485,8 +485,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.1.tgz",
             "integrity": "sha512-9e7jj549ZI+RxY21Cl0t8uBnWyb22HzILupyHZjYEVK//5TT/1bZodU+yUbLnPdoYViBBnNWbxp4zYjGV0zUGw==",
             "requires": {
-                "@types/node": "*",
-                "@types/range-parser": "*"
+                "@types/node": "10.17.13",
+                "@types/range-parser": "1.2.3"
             }
         },
         "@types/express-session": {
@@ -494,8 +494,8 @@
             "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.15.16.tgz",
             "integrity": "sha512-vWQpNt9t/zc4bTX+Ow5powZb9n3NwOM0SYsAJ7PYj5vliB6FA40ye5sW5fZTw8+ekbzJf/sgvtQocf7IryJBJw==",
             "requires": {
-                "@types/express": "*",
-                "@types/node": "*"
+                "@types/express": "4.17.2",
+                "@types/node": "10.17.13"
             }
         },
         "@types/express-validator": {
@@ -503,7 +503,7 @@
             "resolved": "https://registry.npmjs.org/@types/express-validator/-/express-validator-3.0.0.tgz",
             "integrity": "sha512-LusnB0YhTXpBT25PXyGPQlK7leE1e41Vezq1hHEUwjfkopM1Pkv2X2Ppxqh9c+w/HZ6Udzki8AJotKNjDTGdkQ==",
             "requires": {
-                "express-validator": "*"
+                "express-validator": "5.3.1"
             }
         },
         "@types/formidable": {
@@ -511,8 +511,8 @@
             "resolved": "https://registry.npmjs.org/@types/formidable/-/formidable-1.0.31.tgz",
             "integrity": "sha512-dIhM5t8lRP0oWe2HF8MuPvdd1TpPTjhDMAqemcq6oIZQCBQTovhBAdTQ5L5veJB4pdQChadmHuxtB0YzqvfU3Q==",
             "requires": {
-                "@types/events": "*",
-                "@types/node": "*"
+                "@types/events": "3.0.0",
+                "@types/node": "10.17.13"
             }
         },
         "@types/gapi": {
@@ -525,9 +525,9 @@
             "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
             "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
             "requires": {
-                "@types/events": "*",
-                "@types/minimatch": "*",
-                "@types/node": "*"
+                "@types/events": "3.0.0",
+                "@types/minimatch": "3.0.3",
+                "@types/node": "10.17.13"
             }
         },
         "@types/jquery": {
@@ -535,7 +535,7 @@
             "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.31.tgz",
             "integrity": "sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg==",
             "requires": {
-                "@types/sizzle": "*"
+                "@types/sizzle": "2.3.2"
             }
         },
         "@types/jquery-awesome-cursor": {
@@ -543,7 +543,7 @@
             "resolved": "https://registry.npmjs.org/@types/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.0.tgz",
             "integrity": "sha512-tNou39eBTgyQtQGzcynUblExZdZiDqg5xuorANsoIfwBRBZZpHOP8wT/iDSR/qSq2rsu1KuQEfoC8z2L9YSp8A==",
             "requires": {
-                "@types/jquery": "*"
+                "@types/jquery": "3.3.31"
             }
         },
         "@types/jsonwebtoken": {
@@ -551,7 +551,7 @@
             "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.5.tgz",
             "integrity": "sha512-VGM1gb+LwsQ5EPevvbvdnKncajBdYqNcrvixBif1BsiDQiSF1q+j4bBTvKC6Bt9n2kqNSx+yNTY2TVJ360E7EQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/keygrip": {
@@ -570,7 +570,7 @@
             "integrity": "sha512-j5AcZo7dbMxHoOimcHEIh0JZe5e1b8q8AqGSpZJrYc7xOgCIP79cIjTdx5jSDLtySnQDwkDTqwlC7Xw7uXw7qg==",
             "dev": true,
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/mime": {
@@ -588,7 +588,7 @@
             "resolved": "https://registry.npmjs.org/@types/mobile-detect/-/mobile-detect-1.3.4.tgz",
             "integrity": "sha512-MGBTvT5c7aH8eX6szFYP3dWPryNLt5iGlo31XNaJtt8o6jsg6tjn99eEMq9l8T6cPZymsr+J4Jth8+/G/04ZDw==",
             "requires": {
-                "mobile-detect": "*"
+                "mobile-detect": "1.4.4"
             }
         },
         "@types/mocha": {
@@ -601,8 +601,8 @@
             "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.3.14.tgz",
             "integrity": "sha512-Ie0Fjoifm/TPY2rNOgixzhNSjDgxgR0dMKQk9XqUXHnkfuw26SpbMXjwECfxSnEdG1bH6bIlpLIK7HvGHQhzqg==",
             "requires": {
-                "@types/bson": "*",
-                "@types/node": "*"
+                "@types/bson": "4.0.1",
+                "@types/node": "10.17.13"
             }
         },
         "@types/mongoose": {
@@ -610,8 +610,8 @@
             "resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.5.38.tgz",
             "integrity": "sha512-W+vLJ4t0DUQhnV/ivLBLVCOvx3UnU/HgrKrEeHCUwE9VGDTdoOQOgOTiElErf+ome9zZUek6VZil5t7HfJvO+w==",
             "requires": {
-                "@types/mongodb": "*",
-                "@types/node": "*"
+                "@types/mongodb": "3.3.14",
+                "@types/node": "10.17.13"
             }
         },
         "@types/node": {
@@ -624,7 +624,7 @@
             "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-4.6.8.tgz",
             "integrity": "sha512-IX1P3bxDP1VIdZf6/kIWYNmSejkYm9MOyMEtoDFi4DVzKjJ3kY4GhOcOAKs6lZRjqVVmF9UjPOZXuQczlpZThw==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/oauth": {
@@ -632,7 +632,7 @@
             "resolved": "https://registry.npmjs.org/@types/oauth/-/oauth-0.9.1.tgz",
             "integrity": "sha512-a1iY62/a3yhZ7qH7cNUsxoI3U/0Fe9+RnuFrpTKr+0WVOzbKlSLojShCKe20aOD1Sppv+i8Zlq0pLDuTJnwS4A==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/orderedmap": {
@@ -650,7 +650,7 @@
             "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.2.tgz",
             "integrity": "sha512-Pf39AYKf8q+YoONym3150cEwfUD66dtwHJWvbeOzKxnA0GZZ/vAXhNWv9vMhKyRQBQZiQyWQnhYBEBlKW6G8wg==",
             "requires": {
-                "@types/express": "*"
+                "@types/express": "4.17.2"
             }
         },
         "@types/passport-google-oauth20": {
@@ -658,9 +658,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-google-oauth20/-/passport-google-oauth20-2.0.3.tgz",
             "integrity": "sha512-6EUEGzEg4acwowvgR/yVZIj8S2Kkwc6JmlY2/wnM1wJHNz20o7s1TIGrxnah8ymLgJasYDpy95P3TMMqlmetPw==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*",
-                "@types/passport-oauth2": "*"
+                "@types/express": "4.17.2",
+                "@types/passport": "1.0.2",
+                "@types/passport-oauth2": "1.4.8"
             }
         },
         "@types/passport-local": {
@@ -668,9 +668,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.33.tgz",
             "integrity": "sha512-+rn6ZIxje0jZ2+DAiWFI8vGG7ZFKB0hXx2cUdMmudSWsigSq6ES7Emso46r4HJk0qCgrZVfI8sJiM7HIYf4SbA==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*",
-                "@types/passport-strategy": "*"
+                "@types/express": "4.17.2",
+                "@types/passport": "1.0.2",
+                "@types/passport-strategy": "0.2.35"
             }
         },
         "@types/passport-oauth2": {
@@ -678,9 +678,9 @@
             "resolved": "https://registry.npmjs.org/@types/passport-oauth2/-/passport-oauth2-1.4.8.tgz",
             "integrity": "sha512-tlX16wyFE5YJR2pHpZ308dgB1MV9/Ra2wfQh71eWk+/umPoD1Rca2D4N5M27W7nZm1wqUNGTk1I864nHvEgiFA==",
             "requires": {
-                "@types/express": "*",
-                "@types/oauth": "*",
-                "@types/passport": "*"
+                "@types/express": "4.17.2",
+                "@types/oauth": "0.9.1",
+                "@types/passport": "1.0.2"
             }
         },
         "@types/passport-strategy": {
@@ -688,8 +688,8 @@
             "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
             "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
             "requires": {
-                "@types/express": "*",
-                "@types/passport": "*"
+                "@types/express": "4.17.2",
+                "@types/passport": "1.0.2"
             }
         },
         "@types/pdfjs-dist": {
@@ -707,9 +707,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-commands/-/prosemirror-commands-1.0.1.tgz",
             "integrity": "sha512-GeE12m8VT9N1JrzoY//946IX8ZyQOLNmvryJ+BNQs/HvhmXW9EWOcWUE6OBRtxK7Y8SrzSOwx4XmqSgVmK3tGQ==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.11.2"
             }
         },
         "@types/prosemirror-history": {
@@ -717,8 +717,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-history/-/prosemirror-history-1.0.1.tgz",
             "integrity": "sha512-BYyPJlWDo3VEnWS5X2DCHXrrAKEjdbCe1DUjGL6R/8hmwMFe3iMJGYdBkOXU1FfkTpw7Z+PlwY/pMyeelVydmg==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-inputrules": {
@@ -726,8 +726,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
             "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-keymap": {
@@ -735,8 +735,8 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
             "integrity": "sha512-8IjM8ySmoZps9Tn+aKfB4ZR6zoNOjeQfAc9YLQujYXHJB6tdGWV0cbTuoT4QmZOR1iecN1EJ6E9RiRUBk796kQ==",
             "requires": {
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.11.2"
             }
         },
         "@types/prosemirror-menu": {
@@ -744,9 +744,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-menu/-/prosemirror-menu-1.0.1.tgz",
             "integrity": "sha512-wVGc6G7uYRvjIuVwV0zKSLwntFH1wanFwM1fDkq2YcUrLhuj4zZ1i7IPe+yqSoPm7JfmjiDEgHXTpafmwLKJrA==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-view": "1.11.2"
             }
         },
         "@types/prosemirror-model": {
@@ -754,7 +754,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-model/-/prosemirror-model-1.7.2.tgz",
             "integrity": "sha512-2l+yXvidg3AUHN07mO4Jd8Q84fo6ksFsy7LHUurLYrZ74uTahBp2fzcO49AKZMzww2EulXJ40Kl/OFaQ/7A1fw==",
             "requires": {
-                "@types/orderedmap": "*"
+                "@types/orderedmap": "1.0.0"
             }
         },
         "@types/prosemirror-schema-basic": {
@@ -762,7 +762,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-basic/-/prosemirror-schema-basic-1.0.1.tgz",
             "integrity": "sha512-IOQAYf1urifbH+Zwbq5XfFOUMNCbEnvIqpuSAE8SUt00nDAoH62T/S8Qhu8LuF++KQbyXb7fdMp352zkPW9Hmw==",
             "requires": {
-                "@types/prosemirror-model": "*"
+                "@types/prosemirror-model": "1.7.2"
             }
         },
         "@types/prosemirror-schema-list": {
@@ -770,9 +770,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz",
             "integrity": "sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA==",
             "requires": {
-                "@types/orderedmap": "*",
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*"
+                "@types/orderedmap": "1.0.0",
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3"
             }
         },
         "@types/prosemirror-state": {
@@ -780,9 +780,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.2.3.tgz",
             "integrity": "sha512-6m433Hubix9bx+JgcLW7zzyiZuzwjq5mBdSMYY4Yi5c5ZpV2RiVmg7Cy6f9Thtts8vuztilw+PczJAgDm1Frfw==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-transform": "*",
-                "@types/prosemirror-view": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-transform": "1.1.1",
+                "@types/prosemirror-view": "1.11.2"
             }
         },
         "@types/prosemirror-transform": {
@@ -790,7 +790,7 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-transform/-/prosemirror-transform-1.1.1.tgz",
             "integrity": "sha512-yYCYSoiRH+Wcbl8GJc0PFCzeyMzNQ1vL2xrHHSXZuNcIlH75VoiKrZFeZ6BS9cl8mYXjZrlmdBe8YOxYvyKM6A==",
             "requires": {
-                "@types/prosemirror-model": "*"
+                "@types/prosemirror-model": "1.7.2"
             }
         },
         "@types/prosemirror-view": {
@@ -798,9 +798,9 @@
             "resolved": "https://registry.npmjs.org/@types/prosemirror-view/-/prosemirror-view-1.11.2.tgz",
             "integrity": "sha512-EKcQmR4KdkFZU13wS5pWrkSojRCPGqz/l/uzpZFfW5cgdr7fQsftf2/ttvIjpk1a94ISifEY4UZwflVJ+uL4Rg==",
             "requires": {
-                "@types/prosemirror-model": "*",
-                "@types/prosemirror-state": "*",
-                "@types/prosemirror-transform": "*"
+                "@types/prosemirror-model": "1.7.2",
+                "@types/prosemirror-state": "1.2.3",
+                "@types/prosemirror-transform": "1.1.1"
             }
         },
         "@types/pug": {
@@ -818,7 +818,7 @@
             "resolved": "https://registry.npmjs.org/@types/rc-switch/-/rc-switch-1.9.0.tgz",
             "integrity": "sha512-L3ZQ2/1GAaiKuQTMO/2sRdhnNNVtnnvdE0ZOL3/+v54j5LguOvYqTSOHPk9nLPi5va3pdRN1MTce3JkJvGZ65A==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/react": {
@@ -826,8 +826,8 @@
             "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.17.tgz",
             "integrity": "sha512-UP27In4fp4sWF5JgyV6pwVPAQM83Fj76JOcg02X5BZcpSu5Wx+fP9RMqc2v0ssBoQIFvD5JdKY41gjJJKmw6Bg==",
             "requires": {
-                "@types/prop-types": "*",
-                "csstype": "^2.2.0"
+                "@types/prop-types": "15.7.3",
+                "csstype": "2.6.6"
             }
         },
         "@types/react-autosuggest": {
@@ -835,7 +835,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-autosuggest/-/react-autosuggest-9.3.13.tgz",
             "integrity": "sha512-J1RB5KAIk6vOJ+TkIE+EqjCWBjXxjobzeA6D9KrS64kzrt6ixC6uSoKMFnG6ByeWoC+1g0756NILCpIpTV62dw==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/react-color": {
@@ -843,7 +843,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-color/-/react-color-2.17.3.tgz",
             "integrity": "sha512-ewFUB9mNXuqT2UMbiYNqXiUWt857VinGaElhX0Gk+kT1BrXel0imzRp1FeWntHpr+uHkKAnJbr5e4Yc4vP1BRg==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/react-dom": {
@@ -852,7 +852,7 @@
             "integrity": "sha512-fya9xteU/n90tda0s+FtN5Ym4tbgxpq/hb/Af24dvs6uYnYn+fspaxw5USlw0R8apDNwxsqumdRoCoKitckQqw==",
             "dev": true,
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/react-measure": {
@@ -860,7 +860,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.5.tgz",
             "integrity": "sha512-T1Bpt8FlWbDhoInUaNrjTOiVRpRJmrRcqhFJxLGBq1VjaqBLHCvUPapgdKMWEIX4Oqsa1SSKjtNkNJGy6WAAZg==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/react-table": {
@@ -868,7 +868,7 @@
             "resolved": "https://registry.npmjs.org/@types/react-table/-/react-table-6.8.6.tgz",
             "integrity": "sha512-mCgyjD1KiMfZMHixOEzv7qXh5TSfmvgNbOb8qKLcTJbnGgsVSalcEdrNqASyaMp79MvdbMzxAcFQ3lftzmH7MA==",
             "requires": {
-                "@types/react": "*"
+                "@types/react": "16.9.17"
             }
         },
         "@types/request": {
@@ -876,10 +876,10 @@
             "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
             "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
             "requires": {
-                "@types/caseless": "*",
-                "@types/node": "*",
-                "@types/tough-cookie": "*",
-                "form-data": "^2.5.0"
+                "@types/caseless": "0.12.2",
+                "@types/node": "10.17.13",
+                "@types/tough-cookie": "2.3.6",
+                "form-data": "2.5.1"
             }
         },
         "@types/request-promise": {
@@ -887,8 +887,8 @@
             "resolved": "https://registry.npmjs.org/@types/request-promise/-/request-promise-4.1.45.tgz",
             "integrity": "sha512-KFagTY/a7CzAj86DkhaAtqP0ViYTNam+CfEokSwtPFUIuq9Qrq+Rq2X4nuaB6OJmM2s0xWeiS085Ro7vR0tt9Q==",
             "requires": {
-                "@types/bluebird": "*",
-                "@types/request": "*"
+                "@types/bluebird": "3.5.29",
+                "@types/request": "2.48.4"
             }
         },
         "@types/rimraf": {
@@ -896,8 +896,8 @@
             "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-2.0.3.tgz",
             "integrity": "sha512-dZfyfL/u9l/oi984hEXdmAjX3JHry7TLWw43u1HQ8HhPv6KtfxnrZ3T/bleJ0GEvnk9t5sM7eePkgMqz3yBcGg==",
             "requires": {
-                "@types/glob": "*",
-                "@types/node": "*"
+                "@types/glob": "7.1.1",
+                "@types/node": "10.17.13"
             }
         },
         "@types/serve-static": {
@@ -905,8 +905,8 @@
             "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz",
             "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==",
             "requires": {
-                "@types/express-serve-static-core": "*",
-                "@types/mime": "*"
+                "@types/express-serve-static-core": "4.17.1",
+                "@types/mime": "2.0.1"
             }
         },
         "@types/sharp": {
@@ -914,7 +914,7 @@
             "resolved": "https://registry.npmjs.org/@types/sharp/-/sharp-0.23.1.tgz",
             "integrity": "sha512-iBRM9RjRF9pkIkukk6imlxfaKMRuiRND8L0yYKl5PJu5uLvxuNzp5f0x8aoTG5VX85M8O//BwbttzFVZL1j/FQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/shelljs": {
@@ -922,8 +922,8 @@
             "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.6.tgz",
             "integrity": "sha512-svx2eQS268awlppL/P8wgDLBrsDXdKznABHJcuqXyWpSKJgE1s2clXlBvAwbO/lehTmG06NtEWJRkAk4tAgenA==",
             "requires": {
-                "@types/glob": "*",
-                "@types/node": "*"
+                "@types/glob": "7.1.1",
+                "@types/node": "10.17.13"
             }
         },
         "@types/sizzle": {
@@ -936,7 +936,7 @@
             "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.4.tgz",
             "integrity": "sha512-cI98INy7tYnweTsUlp8ocveVdAxENUThO0JsLSCs51cjOP2yV5Mqo5QszMDPckyRRA+PO6+wBgKvGvHUCc23TQ==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/socket.io-client": {
@@ -976,7 +976,7 @@
             "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz",
             "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=",
             "requires": {
-                "typescript": "*"
+                "typescript": "3.7.4"
             }
         },
         "@types/uglify-js": {
@@ -984,7 +984,7 @@
             "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
             "integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
             "requires": {
-                "source-map": "^0.6.1"
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -999,7 +999,7 @@
             "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.6.tgz",
             "integrity": "sha512-cCdlC/1kGEZdEglzOieLDYBxHsvEOIg7kp/2FYyVR9Pxakq+Qf/inL3RKQ+PA8gOlI/NnL+fXmQH12nwcGzsHw==",
             "requires": {
-                "@types/node": "*"
+                "@types/node": "10.17.13"
             }
         },
         "@types/webpack": {
@@ -1007,12 +1007,12 @@
             "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.1.tgz",
             "integrity": "sha512-n9fP8UrMxOi1wiM3oM+vMZHMJJ7WoQohqd63C20cmKOFkNEy9Q8hyZyDR6PWdvSYt3V3A7cwDq/kWxHlRYYZEg==",
             "requires": {
-                "@types/anymatch": "*",
-                "@types/node": "*",
-                "@types/tapable": "*",
-                "@types/uglify-js": "*",
-                "@types/webpack-sources": "*",
-                "source-map": "^0.6.0"
+                "@types/anymatch": "1.3.1",
+                "@types/node": "10.17.13",
+                "@types/tapable": "1.0.4",
+                "@types/uglify-js": "3.0.4",
+                "@types/webpack-sources": "0.1.5",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -1028,10 +1028,10 @@
             "integrity": "sha512-DzNJJ6ah/6t1n8sfAgQyEbZ/OMmFcF9j9P3aesnm7G6/iBFR/qiGin8K89J0RmaWIBzhTMdDg3I5PmKmSv7N9w==",
             "dev": true,
             "requires": {
-                "@types/connect": "*",
-                "@types/memory-fs": "*",
-                "@types/webpack": "*",
-                "loglevel": "^1.6.2"
+                "@types/connect": "3.4.32",
+                "@types/memory-fs": "0.3.2",
+                "@types/webpack": "4.41.1",
+                "loglevel": "1.6.3"
             }
         },
         "@types/webpack-hot-middleware": {
@@ -1040,8 +1040,8 @@
             "integrity": "sha512-J+Zk7c99pMnPcxWpPY7CEdc4jhPFX1SVPrqXTzinoF8ea+OmIiHa+oOdVI7leMQFGZ6G9e9Yo1uNPhLVr/R8Uw==",
             "dev": true,
             "requires": {
-                "@types/connect": "*",
-                "@types/webpack": "*"
+                "@types/connect": "3.4.32",
+                "@types/webpack": "4.41.1"
             }
         },
         "@types/webpack-sources": {
@@ -1049,9 +1049,9 @@
             "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.5.tgz",
             "integrity": "sha512-zfvjpp7jiafSmrzJ2/i3LqOyTYTuJ7u1KOXlKgDlvsj9Rr0x7ZiYu5lZbXwobL7lmsRNtPXlBfmaUD8eU2Hu8w==",
             "requires": {
-                "@types/node": "*",
-                "@types/source-list-map": "*",
-                "source-map": "^0.6.1"
+                "@types/node": "10.17.13",
+                "@types/source-list-map": "0.1.2",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -1117,7 +1117,7 @@
             "dev": true,
             "requires": {
                 "@webassemblyjs/ast": "1.8.5",
-                "mamacro": "^0.0.3"
+                "mamacro": "0.0.3"
             }
         },
         "@webassemblyjs/helper-wasm-bytecode": {
@@ -1144,7 +1144,7 @@
             "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==",
             "dev": true,
             "requires": {
-                "@xtuc/ieee754": "^1.2.0"
+                "@xtuc/ieee754": "1.2.0"
             }
         },
         "@webassemblyjs/leb128": {
@@ -1270,7 +1270,7 @@
             "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
             "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
             "requires": {
-                "event-target-shim": "^5.0.0"
+                "event-target-shim": "5.0.1"
             }
         },
         "accepts": {
@@ -1278,7 +1278,7 @@
             "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
             "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
             "requires": {
-                "mime-types": "~2.1.24",
+                "mime-types": "2.1.24",
                 "negotiator": "0.6.2"
             }
         },
@@ -1292,7 +1292,7 @@
             "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
             "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
             "requires": {
-                "acorn": "^4.0.4"
+                "acorn": "4.0.13"
             },
             "dependencies": {
                 "acorn": {
@@ -1328,7 +1328,7 @@
             "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
             "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
             "requires": {
-                "es6-promisify": "^5.0.0"
+                "es6-promisify": "5.0.0"
             }
         },
         "ajv": {
@@ -1336,10 +1336,10 @@
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
             "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
             "requires": {
-                "fast-deep-equal": "^2.0.1",
-                "fast-json-stable-stringify": "^2.0.0",
-                "json-schema-traverse": "^0.4.1",
-                "uri-js": "^4.2.2"
+                "fast-deep-equal": "2.0.1",
+                "fast-json-stable-stringify": "2.0.0",
+                "json-schema-traverse": "0.4.1",
+                "uri-js": "4.2.2"
             }
         },
         "ajv-errors": {
@@ -1357,9 +1357,9 @@
             "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
             "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
             "requires": {
-                "kind-of": "^3.0.2",
-                "longest": "^1.0.1",
-                "repeat-string": "^1.5.2"
+                "kind-of": "3.2.2",
+                "longest": "1.0.1",
+                "repeat-string": "1.6.1"
             },
             "dependencies": {
                 "kind-of": {
@@ -1367,7 +1367,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -1387,7 +1387,7 @@
             "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
             "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
             "requires": {
-                "string-width": "^2.0.0"
+                "string-width": "2.1.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -1405,8 +1405,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -1414,7 +1414,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -1430,7 +1430,7 @@
             "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
             "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
             "requires": {
-                "array-back": "^3.0.1"
+                "array-back": "3.1.0"
             },
             "dependencies": {
                 "array-back": {
@@ -1466,8 +1466,8 @@
             "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
             "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
             "requires": {
-                "micromatch": "^3.1.4",
-                "normalize-path": "^2.1.1"
+                "micromatch": "3.1.10",
+                "normalize-path": "2.1.1"
             },
             "dependencies": {
                 "normalize-path": {
@@ -1475,7 +1475,7 @@
                     "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
                     "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
                     "requires": {
-                        "remove-trailing-separator": "^1.0.1"
+                        "remove-trailing-separator": "1.1.0"
                     }
                 }
             }
@@ -1490,13 +1490,13 @@
             "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz",
             "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==",
             "requires": {
-                "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"
+                "archiver-utils": "2.1.0",
+                "async": "2.6.3",
+                "buffer-crc32": "0.2.13",
+                "glob": "7.1.4",
+                "readable-stream": "3.4.0",
+                "tar-stream": "2.1.0",
+                "zip-stream": "2.1.2"
             },
             "dependencies": {
                 "bl": {
@@ -1504,7 +1504,7 @@
                     "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
                     "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
                     "requires": {
-                        "readable-stream": "^3.0.1"
+                        "readable-stream": "3.4.0"
                     }
                 },
                 "readable-stream": {
@@ -1512,9 +1512,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "tar-stream": {
@@ -1522,11 +1522,11 @@
                     "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
                     "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
                     "requires": {
-                        "bl": "^3.0.0",
-                        "end-of-stream": "^1.4.1",
-                        "fs-constants": "^1.0.0",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^3.1.1"
+                        "bl": "3.0.0",
+                        "end-of-stream": "1.4.1",
+                        "fs-constants": "1.0.0",
+                        "inherits": "2.0.3",
+                        "readable-stream": "3.4.0"
                     }
                 }
             }
@@ -1536,16 +1536,16 @@
             "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz",
             "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==",
             "requires": {
-                "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"
+                "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.3.6"
             }
         },
         "are-we-there-yet": {
@@ -1553,8 +1553,8 @@
             "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
             "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
             "requires": {
-                "delegates": "^1.0.0",
-                "readable-stream": "^2.0.6"
+                "delegates": "1.0.0",
+                "readable-stream": "2.3.6"
             }
         },
         "argparse": {
@@ -1562,7 +1562,7 @@
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
             "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
             "requires": {
-                "sprintf-js": "~1.0.2"
+                "sprintf-js": "1.0.3"
             }
         },
         "arr-diff": {
@@ -1585,7 +1585,7 @@
             "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
             "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
             "requires": {
-                "typical": "^2.6.1"
+                "typical": "2.6.1"
             }
         },
         "array-batcher": {
@@ -1593,11 +1593,11 @@
             "resolved": "https://registry.npmjs.org/array-batcher/-/array-batcher-1.2.3.tgz",
             "integrity": "sha512-/IOrwn4ZJi7YqTZrs3k+wQN5nKhjtTqL5ZKkzB+sKJlPeJzpMnRc3o8T9yt8/ZJiSldd+PwTHjM+//UsaszOOw==",
             "requires": {
-                "@types/node": "^12.7.5",
-                "chai": "^4.2.0",
-                "mocha": "^6.2.0",
-                "request": "^2.88.0",
-                "request-promise": "^4.2.4"
+                "@types/node": "12.12.3",
+                "chai": "4.2.0",
+                "mocha": "6.2.2",
+                "request": "2.88.0",
+                "request-promise": "4.2.5"
             },
             "dependencies": {
                 "@types/node": {
@@ -1620,7 +1620,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "assert-plus": {
@@ -1648,9 +1648,9 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "debug": {
@@ -1658,7 +1658,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.1"
                     }
                 },
                 "find-up": {
@@ -1666,7 +1666,7 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "form-data": {
@@ -1674,9 +1674,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "get-caller-file": {
@@ -1689,12 +1689,12 @@
                     "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
                     "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "har-validator": {
@@ -1702,8 +1702,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "he": {
@@ -1716,9 +1716,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "is-fullwidth-code-point": {
@@ -1731,8 +1731,8 @@
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "mocha": {
@@ -1780,7 +1780,7 @@
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "qs": {
@@ -1793,26 +1793,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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.3"
                     }
                 },
                 "require-main-filename": {
@@ -1825,9 +1825,9 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -1835,7 +1835,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "supports-color": {
@@ -1843,7 +1843,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
                     "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "which-module": {
@@ -1856,9 +1856,9 @@
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -1871,16 +1871,16 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
                     "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
                     "requires": {
-                        "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.1"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -1888,8 +1888,8 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -1916,7 +1916,7 @@
             "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
             "dev": true,
             "requires": {
-                "array-uniq": "^1.0.1"
+                "array-uniq": "1.0.3"
             }
         },
         "array-uniq": {
@@ -1951,7 +1951,7 @@
             "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
             "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
             "requires": {
-                "safer-buffer": "~2.1.0"
+                "safer-buffer": "2.1.2"
             }
         },
         "asn1.js": {
@@ -1959,9 +1959,9 @@
             "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
             "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
             "requires": {
-                "bn.js": "^4.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0"
+                "bn.js": "4.11.8",
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "assert": {
@@ -1970,7 +1970,7 @@
             "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
             "dev": true,
             "requires": {
-                "object-assign": "^4.1.1",
+                "object-assign": "4.1.1",
                 "util": "0.10.3"
             },
             "dependencies": {
@@ -1982,7 +1982,7 @@
                 },
                 "util": {
                     "version": "0.10.3",
-                    "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+                    "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
                     "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
                     "dev": true,
                     "requires": {
@@ -2016,7 +2016,7 @@
             "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
             "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
             "requires": {
-                "lodash": "^4.17.14"
+                "lodash": "4.17.15"
             }
         },
         "async-each": {
@@ -2050,14 +2050,14 @@
             "integrity": "sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==",
             "dev": true,
             "requires": {
-                "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"
+                "chalk": "2.4.2",
+                "enhanced-resolve": "4.1.0",
+                "loader-utils": "1.2.3",
+                "lodash": "4.17.15",
+                "micromatch": "3.1.10",
+                "mkdirp": "0.5.1",
+                "source-map-support": "0.5.12",
+                "webpack-log": "1.2.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -2066,7 +2066,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -2075,9 +2075,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -2086,7 +2086,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -2107,9 +2107,9 @@
             "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
             "dev": true,
             "requires": {
-                "chalk": "^1.1.3",
-                "esutils": "^2.0.2",
-                "js-tokens": "^3.0.2"
+                "chalk": "1.1.3",
+                "esutils": "2.0.2",
+                "js-tokens": "3.0.2"
             },
             "dependencies": {
                 "js-tokens": {
@@ -2125,16 +2125,16 @@
             "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.23.tgz",
             "integrity": "sha512-1JiCyXU0t5S2xCbItejCduLGGcKmF3POT0Ujbexog2MI4IlRcIn/kWjkYwCUZlxpON0O5FC635yPl/3slr7cKQ==",
             "requires": {
-                "@babel/helper-module-imports": "^7.0.0",
+                "@babel/helper-module-imports": "7.7.4",
                 "@emotion/hash": "0.7.3",
                 "@emotion/memoize": "0.7.3",
-                "@emotion/serialize": "^0.11.14",
-                "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"
+                "@emotion/serialize": "0.11.14",
+                "babel-plugin-macros": "2.8.0",
+                "babel-plugin-syntax-jsx": "6.18.0",
+                "convert-source-map": "1.7.0",
+                "escape-string-regexp": "1.0.5",
+                "find-root": "1.1.0",
+                "source-map": "0.5.7"
             }
         },
         "babel-plugin-macros": {
@@ -2142,9 +2142,9 @@
             "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz",
             "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==",
             "requires": {
-                "@babel/runtime": "^7.7.2",
-                "cosmiconfig": "^6.0.0",
-                "resolve": "^1.12.0"
+                "@babel/runtime": "7.7.6",
+                "cosmiconfig": "6.0.0",
+                "resolve": "1.13.1"
             },
             "dependencies": {
                 "@babel/runtime": {
@@ -2152,7 +2152,7 @@
                     "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz",
                     "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==",
                     "requires": {
-                        "regenerator-runtime": "^0.13.2"
+                        "regenerator-runtime": "0.13.3"
                     }
                 },
                 "resolve": {
@@ -2160,7 +2160,7 @@
                     "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz",
                     "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==",
                     "requires": {
-                        "path-parse": "^1.0.6"
+                        "path-parse": "1.0.6"
                     }
                 }
             }
@@ -2175,8 +2175,8 @@
             "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
             "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
             "requires": {
-                "core-js": "^2.4.0",
-                "regenerator-runtime": "^0.11.0"
+                "core-js": "2.6.9",
+                "regenerator-runtime": "0.11.1"
             },
             "dependencies": {
                 "core-js": {
@@ -2196,10 +2196,10 @@
             "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
             "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
             "requires": {
-                "babel-runtime": "^6.26.0",
-                "esutils": "^2.0.2",
-                "lodash": "^4.17.4",
-                "to-fast-properties": "^1.0.3"
+                "babel-runtime": "6.26.0",
+                "esutils": "2.0.2",
+                "lodash": "4.17.15",
+                "to-fast-properties": "1.0.3"
             },
             "dependencies": {
                 "to-fast-properties": {
@@ -2229,13 +2229,13 @@
             "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
             "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
             "requires": {
-                "cache-base": "^1.0.1",
-                "class-utils": "^0.3.5",
-                "component-emitter": "^1.2.1",
-                "define-property": "^1.0.0",
-                "isobject": "^3.0.1",
-                "mixin-deep": "^1.2.0",
-                "pascalcase": "^0.1.1"
+                "cache-base": "1.0.1",
+                "class-utils": "0.3.6",
+                "component-emitter": "1.3.0",
+                "define-property": "1.0.0",
+                "isobject": "3.0.1",
+                "mixin-deep": "1.3.2",
+                "pascalcase": "0.1.1"
             },
             "dependencies": {
                 "define-property": {
@@ -2243,7 +2243,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -2251,7 +2251,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -2259,7 +2259,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -2267,9 +2267,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -2315,7 +2315,7 @@
             "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
             "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
             "requires": {
-                "tweetnacl": "^0.14.3"
+                "tweetnacl": "0.14.5"
             }
         },
         "better-assert": {
@@ -2355,7 +2355,7 @@
             "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
             "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
             "requires": {
-                "readable-stream": "^3.0.1"
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -2363,9 +2363,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -2380,7 +2380,7 @@
             "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
             "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
             "requires": {
-                "inherits": "~2.0.0"
+                "inherits": "2.0.3"
             }
         },
         "bluebird": {
@@ -2404,15 +2404,15 @@
             "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
             "requires": {
                 "bytes": "3.1.0",
-                "content-type": "~1.0.4",
+                "content-type": "1.0.4",
                 "debug": "2.6.9",
-                "depd": "~1.1.2",
+                "depd": "1.1.2",
                 "http-errors": "1.7.2",
                 "iconv-lite": "0.4.24",
-                "on-finished": "~2.3.0",
+                "on-finished": "2.3.0",
                 "qs": "6.7.0",
                 "raw-body": "2.4.0",
-                "type-is": "~1.6.17"
+                "type-is": "1.6.18"
             }
         },
         "bonjour": {
@@ -2421,12 +2421,12 @@
             "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
             "dev": true,
             "requires": {
-                "array-flatten": "^2.1.0",
-                "deep-equal": "^1.0.1",
-                "dns-equal": "^1.0.0",
-                "dns-txt": "^2.0.2",
-                "multicast-dns": "^6.0.1",
-                "multicast-dns-service-types": "^1.1.0"
+                "array-flatten": "2.1.2",
+                "deep-equal": "1.1.1",
+                "dns-equal": "1.0.0",
+                "dns-txt": "2.0.2",
+                "multicast-dns": "6.2.3",
+                "multicast-dns-service-types": "1.1.0"
             },
             "dependencies": {
                 "array-flatten": {
@@ -2452,13 +2452,13 @@
             "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
             "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
             "requires": {
-                "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"
+                "ansi-align": "2.0.0",
+                "camelcase": "4.1.0",
+                "chalk": "2.4.2",
+                "cli-boxes": "1.0.0",
+                "string-width": "2.1.1",
+                "term-size": "1.2.0",
+                "widest-line": "2.0.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -2471,7 +2471,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -2479,9 +2479,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "is-fullwidth-code-point": {
@@ -2494,8 +2494,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -2503,7 +2503,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 },
                 "supports-color": {
@@ -2511,7 +2511,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -2521,7 +2521,7 @@
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "requires": {
-                "balanced-match": "^1.0.0",
+                "balanced-match": "1.0.0",
                 "concat-map": "0.0.1"
             }
         },
@@ -2530,16 +2530,16 @@
             "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
             "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
             "requires": {
-                "arr-flatten": "^1.1.0",
-                "array-unique": "^0.3.2",
-                "extend-shallow": "^2.0.1",
-                "fill-range": "^4.0.0",
-                "isobject": "^3.0.1",
-                "repeat-element": "^1.1.2",
-                "snapdragon": "^0.8.1",
-                "snapdragon-node": "^2.0.1",
-                "split-string": "^3.0.2",
-                "to-regex": "^3.0.1"
+                "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.3",
+                "snapdragon": "0.8.2",
+                "snapdragon-node": "2.1.1",
+                "split-string": "3.1.0",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -2547,7 +2547,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -2570,15 +2570,15 @@
         },
         "browserify-aes": {
             "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+            "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
             "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
             "requires": {
-                "buffer-xor": "^1.0.3",
-                "cipher-base": "^1.0.0",
-                "create-hash": "^1.1.0",
-                "evp_bytestokey": "^1.0.3",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "buffer-xor": "1.0.3",
+                "cipher-base": "1.0.4",
+                "create-hash": "1.2.0",
+                "evp_bytestokey": "1.0.3",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "browserify-cipher": {
@@ -2586,9 +2586,9 @@
             "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
             "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
             "requires": {
-                "browserify-aes": "^1.0.4",
-                "browserify-des": "^1.0.0",
-                "evp_bytestokey": "^1.0.0"
+                "browserify-aes": "1.2.0",
+                "browserify-des": "1.0.2",
+                "evp_bytestokey": "1.0.3"
             }
         },
         "browserify-des": {
@@ -2596,19 +2596,19 @@
             "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
             "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
             "requires": {
-                "cipher-base": "^1.0.1",
-                "des.js": "^1.0.0",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "cipher-base": "1.0.4",
+                "des.js": "1.0.0",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "browserify-rsa": {
             "version": "4.0.1",
-            "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
             "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
             "requires": {
-                "bn.js": "^4.1.0",
-                "randombytes": "^2.0.1"
+                "bn.js": "4.11.8",
+                "randombytes": "2.1.0"
             }
         },
         "browserify-sign": {
@@ -2616,13 +2616,13 @@
             "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
             "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
             "requires": {
-                "bn.js": "^4.1.1",
-                "browserify-rsa": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "create-hmac": "^1.1.2",
-                "elliptic": "^6.0.0",
-                "inherits": "^2.0.1",
-                "parse-asn1": "^5.0.0"
+                "bn.js": "4.11.8",
+                "browserify-rsa": "4.0.1",
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "elliptic": "6.5.0",
+                "inherits": "2.0.3",
+                "parse-asn1": "5.1.4"
             }
         },
         "browserify-zlib": {
@@ -2631,7 +2631,7 @@
             "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
             "dev": true,
             "requires": {
-                "pako": "~1.0.5"
+                "pako": "1.0.10"
             }
         },
         "bson": {
@@ -2644,8 +2644,8 @@
             "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
             "integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
             "requires": {
-                "base64-js": "^1.0.2",
-                "ieee754": "^1.1.4"
+                "base64-js": "1.3.0",
+                "ieee754": "1.1.13"
             }
         },
         "buffer-crc32": {
@@ -2703,19 +2703,19 @@
             "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
             "dev": true,
             "requires": {
-                "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"
+                "bluebird": "3.7.2",
+                "chownr": "1.1.2",
+                "glob": "7.1.4",
+                "graceful-fs": "4.2.0",
+                "lru-cache": "4.1.5",
+                "mississippi": "2.0.0",
+                "mkdirp": "0.5.1",
+                "move-concurrently": "1.0.1",
+                "promise-inflight": "1.0.1",
+                "rimraf": "2.7.1",
+                "ssri": "5.3.0",
+                "unique-filename": "1.1.1",
+                "y18n": "4.0.0"
             },
             "dependencies": {
                 "rimraf": {
@@ -2724,7 +2724,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "y18n": {
@@ -2740,15 +2740,15 @@
             "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
             "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
             "requires": {
-                "collection-visit": "^1.0.0",
-                "component-emitter": "^1.2.1",
-                "get-value": "^2.0.6",
-                "has-value": "^1.0.0",
-                "isobject": "^3.0.1",
-                "set-value": "^2.0.0",
-                "to-object-path": "^0.3.0",
-                "union-value": "^1.0.0",
-                "unset-value": "^1.0.0"
+                "collection-visit": "1.0.0",
+                "component-emitter": "1.3.0",
+                "get-value": "2.0.6",
+                "has-value": "1.0.0",
+                "isobject": "3.0.1",
+                "set-value": "2.0.1",
+                "to-object-path": "0.3.0",
+                "union-value": "1.0.1",
+                "unset-value": "1.0.0"
             }
         },
         "callsite": {
@@ -2768,11 +2768,11 @@
         },
         "camelcase-keys": {
             "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
             "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
             "requires": {
-                "camelcase": "^2.0.0",
-                "map-obj": "^1.0.0"
+                "camelcase": "2.1.1",
+                "map-obj": "1.0.1"
             },
             "dependencies": {
                 "camelcase": {
@@ -2787,9 +2787,9 @@
             "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.6.1.tgz",
             "integrity": "sha512-S98rKsPcuhfTcYbtF53UIJhcbgIAK533d1kJKMwsMwAIFgfd58MOyxRud3kktlzWiEkFliaJtvyZCBtud/XVEA==",
             "requires": {
-                "nan": "^2.14.0",
-                "node-pre-gyp": "^0.11.0",
-                "simple-get": "^3.0.3"
+                "nan": "2.14.0",
+                "node-pre-gyp": "0.11.0",
+                "simple-get": "3.0.3"
             }
         },
         "capture-stack-trace": {
@@ -2807,8 +2807,8 @@
             "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
             "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
             "requires": {
-                "align-text": "^0.1.3",
-                "lazy-cache": "^1.0.3"
+                "align-text": "0.1.4",
+                "lazy-cache": "1.0.4"
             }
         },
         "chai": {
@@ -2816,12 +2816,12 @@
             "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
             "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
             "requires": {
-                "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"
+                "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.8"
             }
         },
         "chained-function": {
@@ -2834,11 +2834,11 @@
             "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
             "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
             "requires": {
-                "ansi-styles": "^2.2.1",
-                "escape-string-regexp": "^1.0.2",
-                "has-ansi": "^2.0.0",
-                "strip-ansi": "^3.0.0",
-                "supports-color": "^2.0.0"
+                "ansi-styles": "2.2.1",
+                "escape-string-regexp": "1.0.5",
+                "has-ansi": "2.0.0",
+                "strip-ansi": "3.0.1",
+                "supports-color": "2.0.0"
             }
         },
         "character-parser": {
@@ -2846,7 +2846,7 @@
             "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
             "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
             "requires": {
-                "is-regex": "^1.0.3"
+                "is-regex": "1.0.4"
             }
         },
         "check-error": {
@@ -2859,12 +2859,12 @@
             "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
             "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
             "requires": {
-                "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"
+                "css-select": "1.2.0",
+                "dom-serializer": "0.1.1",
+                "entities": "1.1.2",
+                "htmlparser2": "3.10.1",
+                "lodash": "4.17.15",
+                "parse5": "3.0.3"
             },
             "dependencies": {
                 "parse5": {
@@ -2872,7 +2872,7 @@
                     "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
                     "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
                     "requires": {
-                        "@types/node": "*"
+                        "@types/node": "10.17.13"
                     }
                 }
             }
@@ -2887,18 +2887,18 @@
             "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
             "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
             "requires": {
-                "anymatch": "^2.0.0",
-                "async-each": "^1.0.1",
-                "braces": "^2.3.2",
-                "fsevents": "^1.2.7",
-                "glob-parent": "^3.1.0",
-                "inherits": "^2.0.3",
-                "is-binary-path": "^1.0.0",
-                "is-glob": "^4.0.0",
-                "normalize-path": "^3.0.0",
-                "path-is-absolute": "^1.0.0",
-                "readdirp": "^2.2.1",
-                "upath": "^1.1.1"
+                "anymatch": "2.0.0",
+                "async-each": "1.0.3",
+                "braces": "2.3.2",
+                "fsevents": "1.2.11",
+                "glob-parent": "3.1.0",
+                "inherits": "2.0.3",
+                "is-binary-path": "1.0.1",
+                "is-glob": "4.0.1",
+                "normalize-path": "3.0.0",
+                "path-is-absolute": "1.0.1",
+                "readdirp": "2.2.1",
+                "upath": "1.2.0"
             }
         },
         "chownr": {
@@ -2912,7 +2912,7 @@
             "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
             "dev": true,
             "requires": {
-                "tslib": "^1.9.0"
+                "tslib": "1.10.0"
             }
         },
         "ci-info": {
@@ -2925,8 +2925,8 @@
             "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
             "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "class-transformer": {
@@ -2939,10 +2939,10 @@
             "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
             "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
             "requires": {
-                "arr-union": "^3.1.0",
-                "define-property": "^0.2.5",
-                "isobject": "^3.0.0",
-                "static-extend": "^0.1.1"
+                "arr-union": "3.1.0",
+                "define-property": "0.2.5",
+                "isobject": "3.0.1",
+                "static-extend": "0.1.2"
             },
             "dependencies": {
                 "define-property": {
@@ -2950,7 +2950,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 }
             }
@@ -2965,7 +2965,7 @@
             "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
             "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
             "requires": {
-                "source-map": "~0.6.0"
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -2985,14 +2985,14 @@
             "resolved": "https://registry.npmjs.org/cliss/-/cliss-0.0.2.tgz",
             "integrity": "sha512-6rj9pgdukjT994Md13JCUAgTk91abAKrygL9sAvmHY4F6AKMOV8ccGaxhUUfcBuyg3sundWnn3JE0Mc9W6ZYqw==",
             "requires": {
-                "command-line-usage": "^4.0.1",
-                "deepmerge": "^2.0.0",
-                "get-stdin": "^5.0.1",
+                "command-line-usage": "4.1.0",
+                "deepmerge": "2.2.1",
+                "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"
+                "pipe-functions": "1.3.0",
+                "strip-ansi": "4.0.0",
+                "yargs-parser": "7.0.0"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -3005,7 +3005,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -3015,9 +3015,9 @@
             "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
             "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
             "requires": {
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1",
-                "wrap-ansi": "^2.0.0"
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wrap-ansi": "2.1.0"
             }
         },
         "clj-fuzzy": {
@@ -3031,9 +3031,9 @@
             "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==",
             "dev": true,
             "requires": {
-                "is-plain-object": "^2.0.4",
-                "kind-of": "^6.0.2",
-                "shallow-clone": "^3.0.0"
+                "is-plain-object": "2.0.4",
+                "kind-of": "6.0.2",
+                "shallow-clone": "3.0.1"
             }
         },
         "code-point-at": {
@@ -3046,8 +3046,8 @@
             "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
             "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
             "requires": {
-                "map-visit": "^1.0.0",
-                "object-visit": "^1.0.0"
+                "map-visit": "1.0.0",
+                "object-visit": "1.0.1"
             }
         },
         "color": {
@@ -3055,8 +3055,8 @@
             "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
             "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
             "requires": {
-                "color-convert": "^1.9.1",
-                "color-string": "^1.5.2"
+                "color-convert": "1.9.3",
+                "color-string": "1.5.3"
             }
         },
         "color-convert": {
@@ -3077,8 +3077,8 @@
             "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
             "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
             "requires": {
-                "color-name": "^1.0.0",
-                "simple-swizzle": "^0.2.2"
+                "color-name": "1.1.3",
+                "simple-swizzle": "0.2.2"
             }
         },
         "colors": {
@@ -3091,7 +3091,7 @@
             "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
             "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
             "requires": {
-                "delayed-stream": "~1.0.0"
+                "delayed-stream": "1.0.0"
             }
         },
         "command-line-usage": {
@@ -3099,10 +3099,10 @@
             "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
             "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
             "requires": {
-                "ansi-escape-sequences": "^4.0.0",
-                "array-back": "^2.0.0",
-                "table-layout": "^0.4.2",
-                "typical": "^2.6.1"
+                "ansi-escape-sequences": "4.1.0",
+                "array-back": "2.0.0",
+                "table-layout": "0.4.5",
+                "typical": "2.6.1"
             }
         },
         "commander": {
@@ -3121,15 +3121,15 @@
             "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz",
             "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=",
             "requires": {
-                "commander": "^2.5.0",
-                "detective": "^4.3.1",
-                "glob": "^5.0.15",
-                "graceful-fs": "^4.1.2",
-                "iconv-lite": "^0.4.5",
-                "mkdirp": "^0.5.0",
-                "private": "^0.1.6",
-                "q": "^1.1.2",
-                "recast": "^0.11.17"
+                "commander": "2.20.0",
+                "detective": "4.7.1",
+                "glob": "5.0.15",
+                "graceful-fs": "4.2.0",
+                "iconv-lite": "0.4.24",
+                "mkdirp": "0.5.1",
+                "private": "0.1.8",
+                "q": "1.5.1",
+                "recast": "0.11.23"
             },
             "dependencies": {
                 "glob": {
@@ -3137,11 +3137,11 @@
                     "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
                     "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
                     "requires": {
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "2 || 3",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 }
             }
@@ -3166,10 +3166,10 @@
             "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz",
             "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==",
             "requires": {
-                "buffer-crc32": "^0.2.13",
-                "crc32-stream": "^3.0.1",
-                "normalize-path": "^3.0.0",
-                "readable-stream": "^2.3.6"
+                "buffer-crc32": "0.2.13",
+                "crc32-stream": "3.0.1",
+                "normalize-path": "3.0.0",
+                "readable-stream": "2.3.6"
             }
         },
         "compressible": {
@@ -3178,7 +3178,7 @@
             "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
             "dev": true,
             "requires": {
-                "mime-db": ">= 1.40.0 < 2"
+                "mime-db": "1.40.0"
             }
         },
         "compression": {
@@ -3187,13 +3187,13 @@
             "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
             "dev": true,
             "requires": {
-                "accepts": "~1.3.5",
+                "accepts": "1.3.7",
                 "bytes": "3.0.0",
-                "compressible": "~2.0.16",
+                "compressible": "2.0.17",
                 "debug": "2.6.9",
-                "on-headers": "~1.0.2",
+                "on-headers": "1.0.2",
                 "safe-buffer": "5.1.2",
-                "vary": "~1.1.2"
+                "vary": "1.1.2"
             },
             "dependencies": {
                 "bytes": {
@@ -3215,10 +3215,10 @@
             "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
             "dev": true,
             "requires": {
-                "buffer-from": "^1.0.0",
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.2.2",
-                "typedarray": "^0.0.6"
+                "buffer-from": "1.1.1",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "typedarray": "0.0.6"
             }
         },
         "configstore": {
@@ -3226,12 +3226,12 @@
             "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
             "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
             "requires": {
-                "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"
+                "dot-prop": "4.2.0",
+                "graceful-fs": "4.2.0",
+                "make-dir": "1.3.0",
+                "unique-string": "1.0.0",
+                "write-file-atomic": "2.4.3",
+                "xdg-basedir": "3.0.0"
             }
         },
         "connect-flash": {
@@ -3250,7 +3250,7 @@
             "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-2.0.3.tgz",
             "integrity": "sha512-Vs+QZ/6X6gbCrP1Ls7Oh/wlyY6pgpbPSrUKF5yRT+zd+4GZPNbjNquxquZ+Clv2+03HBXE7T4lVM0PUcaBhihg==",
             "requires": {
-                "mongodb": "^2.0.36"
+                "mongodb": "2.2.36"
             },
             "dependencies": {
                 "mongodb": {
@@ -3273,13 +3273,13 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz",
                     "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=",
                     "requires": {
-                        "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"
+                        "buffer-shims": "1.0.0",
+                        "core-util-is": "1.0.2",
+                        "inherits": "2.0.3",
+                        "isarray": "1.0.0",
+                        "process-nextick-args": "1.0.7",
+                        "string_decoder": "1.0.3",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "string_decoder": {
@@ -3287,7 +3287,7 @@
                     "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
                     "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 }
             }
@@ -3308,10 +3308,10 @@
             "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
             "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
             "requires": {
-                "@types/babel-types": "^7.0.0",
-                "@types/babylon": "^6.16.2",
-                "babel-types": "^6.26.0",
-                "babylon": "^6.18.0"
+                "@types/babel-types": "7.0.7",
+                "@types/babylon": "6.16.5",
+                "babel-types": "6.26.0",
+                "babylon": "6.18.0"
             }
         },
         "constants-browserify": {
@@ -3338,7 +3338,7 @@
             "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
             "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
             "requires": {
-                "safe-buffer": "~5.1.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "cookie": {
@@ -3362,7 +3362,7 @@
             "requires": {
                 "cookies": "0.7.1",
                 "debug": "3.1.0",
-                "on-headers": "~1.0.1",
+                "on-headers": "1.0.2",
                 "safe-buffer": "5.1.1"
             },
             "dependencies": {
@@ -3391,8 +3391,8 @@
             "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.1.tgz",
             "integrity": "sha1-fIphX1SBxhq58WyDNzG8uPZjuZs=",
             "requires": {
-                "depd": "~1.1.1",
-                "keygrip": "~1.0.2"
+                "depd": "1.1.2",
+                "keygrip": "1.0.3"
             }
         },
         "copy-concurrently": {
@@ -3401,12 +3401,12 @@
             "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1",
-                "fs-write-stream-atomic": "^1.0.8",
-                "iferr": "^0.1.5",
-                "mkdirp": "^0.5.1",
-                "rimraf": "^2.5.4",
-                "run-queue": "^1.0.0"
+                "aproba": "1.2.0",
+                "fs-write-stream-atomic": "1.0.10",
+                "iferr": "0.1.5",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1",
+                "run-queue": "1.0.3"
             },
             "dependencies": {
                 "rimraf": {
@@ -3415,7 +3415,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -3431,14 +3431,14 @@
             "integrity": "sha512-Y+SQCF+0NoWQryez2zXn5J5knmr9z/9qSQt7fbL78u83rxmigOy8X5+BFn8CFSuX+nKT8gpYwJX68ekqtQt6ZA==",
             "dev": true,
             "requires": {
-                "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"
+                "cacache": "10.0.4",
+                "find-cache-dir": "1.0.0",
+                "globby": "7.1.1",
+                "is-glob": "4.0.1",
+                "loader-utils": "1.2.3",
+                "minimatch": "3.0.4",
+                "p-limit": "1.3.0",
+                "serialize-javascript": "1.7.0"
             },
             "dependencies": {
                 "p-limit": {
@@ -3447,7 +3447,7 @@
                     "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
                     "dev": true,
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 }
             }
@@ -3467,8 +3467,8 @@
             "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
             "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
             "requires": {
-                "object-assign": "^4",
-                "vary": "^1"
+                "object-assign": "4.1.1",
+                "vary": "1.1.2"
             }
         },
         "cosmiconfig": {
@@ -3476,11 +3476,11 @@
             "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
             "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
             "requires": {
-                "@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"
+                "@types/parse-json": "4.0.0",
+                "import-fresh": "3.2.1",
+                "parse-json": "5.0.0",
+                "path-type": "4.0.0",
+                "yaml": "1.7.2"
             },
             "dependencies": {
                 "path-type": {
@@ -3495,7 +3495,7 @@
             "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
             "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
             "requires": {
-                "buffer": "^5.1.0"
+                "buffer": "5.4.3"
             }
         },
         "crc32-stream": {
@@ -3503,8 +3503,8 @@
             "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz",
             "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==",
             "requires": {
-                "crc": "^3.4.4",
-                "readable-stream": "^3.4.0"
+                "crc": "3.8.0",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -3512,9 +3512,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -3524,8 +3524,8 @@
             "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
             "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "elliptic": "^6.0.0"
+                "bn.js": "4.11.8",
+                "elliptic": "6.5.0"
             }
         },
         "create-emotion": {
@@ -3533,8 +3533,8 @@
             "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-10.0.14.tgz",
             "integrity": "sha512-5G4naKMxokOur+94eDz7iPKBfwzy4wa/+0isnPhxXyosIQHBq7yvBy4jjdZw/nnRm7G3PM7P9Ug8mUmtoqcaHg==",
             "requires": {
-                "@emotion/cache": "^10.0.14",
-                "@emotion/serialize": "^0.11.8",
+                "@emotion/cache": "10.0.19",
+                "@emotion/serialize": "0.11.14",
                 "@emotion/sheet": "0.9.3",
                 "@emotion/utils": "0.11.2"
             }
@@ -3544,32 +3544,32 @@
             "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
             "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
             "requires": {
-                "capture-stack-trace": "^1.0.0"
+                "capture-stack-trace": "1.0.1"
             }
         },
         "create-hash": {
             "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+            "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
             "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
             "requires": {
-                "cipher-base": "^1.0.1",
-                "inherits": "^2.0.1",
-                "md5.js": "^1.3.4",
-                "ripemd160": "^2.0.1",
-                "sha.js": "^2.4.0"
+                "cipher-base": "1.0.4",
+                "inherits": "2.0.3",
+                "md5.js": "1.3.5",
+                "ripemd160": "2.0.2",
+                "sha.js": "2.4.11"
             }
         },
         "create-hmac": {
             "version": "1.1.7",
-            "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+            "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
             "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
             "requires": {
-                "cipher-base": "^1.0.3",
-                "create-hash": "^1.1.0",
-                "inherits": "^2.0.1",
-                "ripemd160": "^2.0.0",
-                "safe-buffer": "^5.0.1",
-                "sha.js": "^2.4.8"
+                "cipher-base": "1.0.4",
+                "create-hash": "1.2.0",
+                "inherits": "2.0.3",
+                "ripemd160": "2.0.2",
+                "safe-buffer": "5.1.2",
+                "sha.js": "2.4.11"
             }
         },
         "create-react-context": {
@@ -3577,8 +3577,8 @@
             "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.3.tgz",
             "integrity": "sha512-CQBmD0+QGgTaxDL3OX1IDXYqjkp2It4RIbcb99jS6AEg27Ga+a9G3JtK6SIu0HBwPLZlmwt9F7UwWA4Bn92Rag==",
             "requires": {
-                "fbjs": "^0.8.0",
-                "gud": "^1.0.0"
+                "fbjs": "0.8.17",
+                "gud": "1.0.0"
             }
         },
         "crel": {
@@ -3592,7 +3592,7 @@
             "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==",
             "dev": true,
             "requires": {
-                "cross-spawn": "^6.0.5"
+                "cross-spawn": "6.0.5"
             }
         },
         "cross-fetch": {
@@ -3617,11 +3617,11 @@
             "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
             "dev": true,
             "requires": {
-                "nice-try": "^1.0.4",
-                "path-key": "^2.0.1",
-                "semver": "^5.5.0",
-                "shebang-command": "^1.2.0",
-                "which": "^1.2.9"
+                "nice-try": "1.0.5",
+                "path-key": "2.0.1",
+                "semver": "5.7.0",
+                "shebang-command": "1.2.0",
+                "which": "1.3.1"
             }
         },
         "crypto-browserify": {
@@ -3629,17 +3629,17 @@
             "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
             "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
             "requires": {
-                "browserify-cipher": "^1.0.0",
-                "browserify-sign": "^4.0.0",
-                "create-ecdh": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "create-hmac": "^1.1.0",
-                "diffie-hellman": "^5.0.0",
-                "inherits": "^2.0.1",
-                "pbkdf2": "^3.0.3",
-                "public-encrypt": "^4.0.0",
-                "randombytes": "^2.0.0",
-                "randomfill": "^1.0.3"
+                "browserify-cipher": "1.0.1",
+                "browserify-sign": "4.0.4",
+                "create-ecdh": "4.0.3",
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "diffie-hellman": "5.0.3",
+                "inherits": "2.0.3",
+                "pbkdf2": "3.0.17",
+                "public-encrypt": "4.0.3",
+                "randombytes": "2.1.0",
+                "randomfill": "1.0.4"
             }
         },
         "crypto-random-string": {
@@ -3653,17 +3653,17 @@
             "integrity": "sha512-OcKJU/lt232vl1P9EEDamhoO9iKY3tIjY5GU+XDLblAykTdgs6Ux9P1hTHve8nFKy5KPpOXOsVI/hIwi3841+w==",
             "dev": true,
             "requires": {
-                "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"
+                "camelcase": "5.3.1",
+                "icss-utils": "4.1.1",
+                "loader-utils": "1.2.3",
+                "normalize-path": "3.0.0",
+                "postcss": "7.0.17",
+                "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.1",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -3678,9 +3678,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -3690,10 +3690,10 @@
             "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
             "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
             "requires": {
-                "boolbase": "~1.0.0",
-                "css-what": "2.1",
+                "boolbase": "1.0.0",
+                "css-what": "2.1.3",
                 "domutils": "1.5.1",
-                "nth-check": "~1.0.1"
+                "nth-check": "1.0.2"
             }
         },
         "css-what": {
@@ -3719,7 +3719,7 @@
             "integrity": "sha512-QXSAu2WBsSRXCPjvI43Y40m6fMevvyRm8JVAuF9ksQz5jha4pWP1wpaK7Yu5oLFc6+XAY+hj8YhefyXcBB53gg==",
             "dev": true,
             "requires": {
-                "cssom": "~0.3.6"
+                "cssom": "0.3.8"
             },
             "dependencies": {
                 "cssom": {
@@ -3740,7 +3740,7 @@
             "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
             "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
             "requires": {
-                "array-find-index": "^1.0.1"
+                "array-find-index": "1.0.2"
             }
         },
         "cyclist": {
@@ -3755,8 +3755,8 @@
             "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
             "dev": true,
             "requires": {
-                "es5-ext": "^0.10.50",
-                "type": "^1.0.1"
+                "es5-ext": "0.10.50",
+                "type": "1.0.1"
             }
         },
         "d3-format": {
@@ -3769,7 +3769,7 @@
             "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
             "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
             "requires": {
-                "assert-plus": "^1.0.0"
+                "assert-plus": "1.0.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -3785,9 +3785,9 @@
             "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
             "dev": true,
             "requires": {
-                "abab": "^2.0.0",
-                "whatwg-mimetype": "^2.2.0",
-                "whatwg-url": "^7.0.0"
+                "abab": "2.0.3",
+                "whatwg-mimetype": "2.3.0",
+                "whatwg-url": "7.1.0"
             }
         },
         "dateformat": {
@@ -3796,8 +3796,8 @@
             "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
             "dev": true,
             "requires": {
-                "get-stdin": "^4.0.1",
-                "meow": "^3.3.0"
+                "get-stdin": "4.0.1",
+                "meow": "3.7.0"
             },
             "dependencies": {
                 "get-stdin": {
@@ -3837,7 +3837,7 @@
             "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
             "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
             "requires": {
-                "mimic-response": "^1.0.0"
+                "mimic-response": "1.0.1"
             }
         },
         "deep-eql": {
@@ -3845,7 +3845,7 @@
             "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
             "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
             "requires": {
-                "type-detect": "^4.0.0"
+                "type-detect": "4.0.8"
             }
         },
         "deep-equal": {
@@ -3854,12 +3854,12 @@
             "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
             "dev": true,
             "requires": {
-                "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"
+                "is-arguments": "1.0.4",
+                "is-date-object": "1.0.1",
+                "is-regex": "1.0.4",
+                "object-is": "1.0.2",
+                "object-keys": "1.1.1",
+                "regexp.prototype.flags": "1.3.0"
             }
         },
         "deep-extend": {
@@ -3884,8 +3884,8 @@
             "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
             "dev": true,
             "requires": {
-                "execa": "^1.0.0",
-                "ip-regex": "^2.1.0"
+                "execa": "1.0.0",
+                "ip-regex": "2.1.0"
             },
             "dependencies": {
                 "execa": {
@@ -3894,13 +3894,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "get-stream": {
@@ -3909,7 +3909,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "pump": {
@@ -3918,8 +3918,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 }
             }
@@ -3929,7 +3929,7 @@
             "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
             "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
             "requires": {
-                "object-keys": "^1.0.12"
+                "object-keys": "1.1.1"
             }
         },
         "define-property": {
@@ -3937,8 +3937,8 @@
             "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
             "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
             "requires": {
-                "is-descriptor": "^1.0.2",
-                "isobject": "^3.0.1"
+                "is-descriptor": "1.0.2",
+                "isobject": "3.0.1"
             },
             "dependencies": {
                 "is-accessor-descriptor": {
@@ -3946,7 +3946,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -3954,7 +3954,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -3962,9 +3962,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -3980,13 +3980,13 @@
             "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
             "dev": true,
             "requires": {
-                "@types/glob": "^7.1.1",
-                "globby": "^6.1.0",
-                "is-path-cwd": "^2.0.0",
-                "is-path-in-cwd": "^2.0.0",
-                "p-map": "^2.0.0",
-                "pify": "^4.0.1",
-                "rimraf": "^2.6.3"
+                "@types/glob": "7.1.1",
+                "globby": "6.1.0",
+                "is-path-cwd": "2.2.0",
+                "is-path-in-cwd": "2.1.0",
+                "p-map": "2.1.0",
+                "pify": "4.0.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "globby": {
@@ -3995,11 +3995,11 @@
                     "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
                     "dev": true,
                     "requires": {
-                        "array-union": "^1.0.1",
-                        "glob": "^7.0.3",
-                        "object-assign": "^4.0.1",
-                        "pify": "^2.0.0",
-                        "pinkie-promise": "^2.0.0"
+                        "array-union": "1.0.2",
+                        "glob": "7.1.4",
+                        "object-assign": "4.1.1",
+                        "pify": "2.3.0",
+                        "pinkie-promise": "2.0.1"
                     },
                     "dependencies": {
                         "pify": {
@@ -4022,7 +4022,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -4047,8 +4047,8 @@
             "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
             "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
             "requires": {
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0"
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "destroy": {
@@ -4078,8 +4078,8 @@
             "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz",
             "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==",
             "requires": {
-                "acorn": "^5.2.1",
-                "defined": "^1.0.0"
+                "acorn": "5.7.3",
+                "defined": "1.0.0"
             }
         },
         "diff": {
@@ -4089,12 +4089,12 @@
         },
         "diffie-hellman": {
             "version": "5.0.3",
-            "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+            "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
             "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "miller-rabin": "^4.0.0",
-                "randombytes": "^2.0.0"
+                "bn.js": "4.11.8",
+                "miller-rabin": "4.0.1",
+                "randombytes": "2.1.0"
             }
         },
         "dir-glob": {
@@ -4103,7 +4103,7 @@
             "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
             "dev": true,
             "requires": {
-                "path-type": "^3.0.0"
+                "path-type": "3.0.0"
             },
             "dependencies": {
                 "path-type": {
@@ -4112,7 +4112,7 @@
                     "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
                     "dev": true,
                     "requires": {
-                        "pify": "^3.0.0"
+                        "pify": "3.0.0"
                     }
                 },
                 "pify": {
@@ -4135,8 +4135,8 @@
             "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
             "dev": true,
             "requires": {
-                "ip": "^1.1.0",
-                "safe-buffer": "^5.0.1"
+                "ip": "1.1.5",
+                "safe-buffer": "5.1.2"
             }
         },
         "dns-txt": {
@@ -4145,7 +4145,7 @@
             "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
             "dev": true,
             "requires": {
-                "buffer-indexof": "^1.0.0"
+                "buffer-indexof": "1.1.1"
             }
         },
         "doctypes": {
@@ -4158,7 +4158,7 @@
             "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
             "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
             "requires": {
-                "@babel/runtime": "^7.1.2"
+                "@babel/runtime": "7.5.5"
             }
         },
         "dom-serializer": {
@@ -4166,8 +4166,8 @@
             "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
             "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
             "requires": {
-                "domelementtype": "^1.3.0",
-                "entities": "^1.1.1"
+                "domelementtype": "1.3.1",
+                "entities": "1.1.2"
             }
         },
         "domain-browser": {
@@ -4187,7 +4187,7 @@
             "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
             "dev": true,
             "requires": {
-                "webidl-conversions": "^4.0.2"
+                "webidl-conversions": "4.0.2"
             }
         },
         "domhandler": {
@@ -4195,7 +4195,7 @@
             "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
             "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
             "requires": {
-                "domelementtype": "1"
+                "domelementtype": "1.3.1"
             }
         },
         "domutils": {
@@ -4203,8 +4203,8 @@
             "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
             "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
             "requires": {
-                "dom-serializer": "0",
-                "domelementtype": "1"
+                "dom-serializer": "0.1.1",
+                "domelementtype": "1.3.1"
             }
         },
         "dot-prop": {
@@ -4212,7 +4212,7 @@
             "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
             "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
             "requires": {
-                "is-obj": "^1.0.0"
+                "is-obj": "1.0.1"
             }
         },
         "dotenv": {
@@ -4231,10 +4231,10 @@
             "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
             "dev": true,
             "requires": {
-                "end-of-stream": "^1.0.0",
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.0.0",
-                "stream-shift": "^1.0.0"
+                "end-of-stream": "1.4.1",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "stream-shift": "1.0.0"
             }
         },
         "dynamic-dedupe": {
@@ -4243,7 +4243,7 @@
             "integrity": "sha1-BuRMIj9eTpTXjvnbI6ZRXOL5YqE=",
             "dev": true,
             "requires": {
-                "xtend": "^4.0.0"
+                "xtend": "4.0.2"
             }
         },
         "ecc-jsbn": {
@@ -4251,8 +4251,8 @@
             "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
             "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
             "requires": {
-                "jsbn": "~0.1.0",
-                "safer-buffer": "^2.1.0"
+                "jsbn": "0.1.1",
+                "safer-buffer": "2.1.2"
             }
         },
         "ecdsa-sig-formatter": {
@@ -4260,7 +4260,7 @@
             "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
             "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
             "requires": {
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "ee-first": {
@@ -4278,13 +4278,13 @@
             "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz",
             "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==",
             "requires": {
-                "bn.js": "^4.4.0",
-                "brorand": "^1.0.1",
-                "hash.js": "^1.0.0",
-                "hmac-drbg": "^1.0.0",
-                "inherits": "^2.0.1",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.0"
+                "bn.js": "4.11.8",
+                "brorand": "1.1.0",
+                "hash.js": "1.1.7",
+                "hmac-drbg": "1.0.1",
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1",
+                "minimalistic-crypto-utils": "1.0.1"
             }
         },
         "emoji-regex": {
@@ -4302,8 +4302,8 @@
             "resolved": "https://registry.npmjs.org/emotion/-/emotion-10.0.23.tgz",
             "integrity": "sha512-H/x+5rJUnSvI0rdYsAFyDfuQwE0poZgTMj5TQsKirLzyHVWqs6CiUponsdE86sisXw0vS60j91HAbidJJeDt1g==",
             "requires": {
-                "babel-plugin-emotion": "^10.0.23",
-                "create-emotion": "^10.0.14"
+                "babel-plugin-emotion": "10.0.23",
+                "create-emotion": "10.0.14"
             }
         },
         "encodeurl": {
@@ -4316,7 +4316,7 @@
             "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
             "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
             "requires": {
-                "iconv-lite": "~0.4.13"
+                "iconv-lite": "0.4.24"
             }
         },
         "end-of-stream": {
@@ -4324,7 +4324,7 @@
             "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
             "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
             "requires": {
-                "once": "^1.4.0"
+                "once": "1.4.0"
             }
         },
         "engine.io": {
@@ -4332,12 +4332,12 @@
             "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz",
             "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==",
             "requires": {
-                "accepts": "~1.3.4",
+                "accepts": "1.3.7",
                 "base64id": "2.0.0",
                 "cookie": "0.3.1",
-                "debug": "~4.1.0",
-                "engine.io-parser": "~2.2.0",
-                "ws": "^7.1.2"
+                "debug": "4.1.1",
+                "engine.io-parser": "2.2.0",
+                "ws": "7.2.1"
             },
             "dependencies": {
                 "debug": {
@@ -4345,7 +4345,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -4362,14 +4362,14 @@
             "requires": {
                 "component-emitter": "1.2.1",
                 "component-inherit": "0.0.3",
-                "debug": "~4.1.0",
-                "engine.io-parser": "~2.2.0",
+                "debug": "4.1.1",
+                "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",
+                "ws": "6.1.4",
+                "xmlhttprequest-ssl": "1.5.5",
                 "yeast": "0.1.2"
             },
             "dependencies": {
@@ -4383,7 +4383,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -4396,7 +4396,7 @@
                     "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
                     "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
                     "requires": {
-                        "async-limiter": "~1.0.0"
+                        "async-limiter": "1.0.1"
                     }
                 }
             }
@@ -4407,10 +4407,10 @@
             "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
             "requires": {
                 "after": "0.8.2",
-                "arraybuffer.slice": "~0.0.7",
+                "arraybuffer.slice": "0.0.7",
                 "base64-arraybuffer": "0.1.5",
                 "blob": "0.0.5",
-                "has-binary2": "~1.0.2"
+                "has-binary2": "1.0.3"
             }
         },
         "enhanced-resolve": {
@@ -4419,9 +4419,9 @@
             "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==",
             "dev": true,
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "memory-fs": "^0.4.0",
-                "tapable": "^1.0.0"
+                "graceful-fs": "4.2.0",
+                "memory-fs": "0.4.1",
+                "tapable": "1.1.3"
             }
         },
         "entities": {
@@ -4434,8 +4434,8 @@
             "resolved": "https://registry.npmjs.org/envify/-/envify-3.4.1.tgz",
             "integrity": "sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=",
             "requires": {
-                "jstransform": "^11.0.3",
-                "through": "~2.3.4"
+                "jstransform": "11.0.3",
+                "through": "2.3.8"
             }
         },
         "errno": {
@@ -4444,7 +4444,7 @@
             "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
             "dev": true,
             "requires": {
-                "prr": "~1.0.1"
+                "prr": "1.0.1"
             }
         },
         "error-ex": {
@@ -4452,7 +4452,7 @@
             "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
             "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
             "requires": {
-                "is-arrayish": "^0.2.1"
+                "is-arrayish": "0.2.1"
             }
         },
         "es-abstract": {
@@ -4460,16 +4460,16 @@
             "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz",
             "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==",
             "requires": {
-                "es-to-primitive": "^1.2.0",
-                "function-bind": "^1.1.1",
-                "has": "^1.0.3",
-                "has-symbols": "^1.0.0",
-                "is-callable": "^1.1.4",
-                "is-regex": "^1.0.4",
-                "object-inspect": "^1.6.0",
-                "object-keys": "^1.1.1",
-                "string.prototype.trimleft": "^2.1.0",
-                "string.prototype.trimright": "^2.1.0"
+                "es-to-primitive": "1.2.0",
+                "function-bind": "1.1.1",
+                "has": "1.0.3",
+                "has-symbols": "1.0.0",
+                "is-callable": "1.1.4",
+                "is-regex": "1.0.4",
+                "object-inspect": "1.6.0",
+                "object-keys": "1.1.1",
+                "string.prototype.trimleft": "2.1.0",
+                "string.prototype.trimright": "2.1.0"
             }
         },
         "es-to-primitive": {
@@ -4477,9 +4477,9 @@
             "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
             "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
             "requires": {
-                "is-callable": "^1.1.4",
-                "is-date-object": "^1.0.1",
-                "is-symbol": "^1.0.2"
+                "is-callable": "1.1.4",
+                "is-date-object": "1.0.1",
+                "is-symbol": "1.0.2"
             }
         },
         "es5-ext": {
@@ -4488,9 +4488,9 @@
             "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==",
             "dev": true,
             "requires": {
-                "es6-iterator": "~2.0.3",
-                "es6-symbol": "~3.1.1",
-                "next-tick": "^1.0.0"
+                "es6-iterator": "2.0.3",
+                "es6-symbol": "3.1.1",
+                "next-tick": "1.0.0"
             }
         },
         "es6-iterator": {
@@ -4499,9 +4499,9 @@
             "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
             "dev": true,
             "requires": {
-                "d": "1",
-                "es5-ext": "^0.10.35",
-                "es6-symbol": "^3.1.1"
+                "d": "1.0.1",
+                "es5-ext": "0.10.50",
+                "es6-symbol": "3.1.1"
             }
         },
         "es6-promise": {
@@ -4514,7 +4514,7 @@
             "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
             "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
             "requires": {
-                "es6-promise": "^4.0.3"
+                "es6-promise": "4.2.8"
             },
             "dependencies": {
                 "es6-promise": {
@@ -4530,8 +4530,8 @@
             "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
             "dev": true,
             "requires": {
-                "d": "1",
-                "es5-ext": "~0.10.14"
+                "d": "1.0.1",
+                "es5-ext": "0.10.50"
             }
         },
         "escape-html": {
@@ -4550,11 +4550,11 @@
             "integrity": "sha512-Q8t2YZ+0e0pc7NRVj3B4tSQ9rim1oi4Fh46k2xhJ2qOiEwhQfdjyEQddWdj7ZFaKmU+5104vn1qrcjEPWq+bgQ==",
             "dev": true,
             "requires": {
-                "esprima": "^3.1.3",
-                "estraverse": "^4.2.0",
-                "esutils": "^2.0.2",
-                "optionator": "^0.8.1",
-                "source-map": "~0.6.1"
+                "esprima": "3.1.3",
+                "estraverse": "4.3.0",
+                "esutils": "2.0.2",
+                "optionator": "0.8.3",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "esprima": {
@@ -4578,8 +4578,8 @@
             "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
             "dev": true,
             "requires": {
-                "esrecurse": "^4.1.0",
-                "estraverse": "^4.1.1"
+                "esrecurse": "4.2.1",
+                "estraverse": "4.3.0"
             }
         },
         "esprima": {
@@ -4593,7 +4593,7 @@
             "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
             "dev": true,
             "requires": {
-                "estraverse": "^4.1.0"
+                "estraverse": "4.3.0"
             }
         },
         "estraverse": {
@@ -4639,7 +4639,7 @@
             "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
             "dev": true,
             "requires": {
-                "original": "^1.0.0"
+                "original": "1.0.2"
             }
         },
         "evp_bytestokey": {
@@ -4647,8 +4647,8 @@
             "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
             "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
             "requires": {
-                "md5.js": "^1.3.4",
-                "safe-buffer": "^5.1.1"
+                "md5.js": "1.3.5",
+                "safe-buffer": "5.1.2"
             }
         },
         "execa": {
@@ -4656,13 +4656,13 @@
             "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
             "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
             "requires": {
-                "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"
+                "cross-spawn": "5.1.0",
+                "get-stream": "3.0.0",
+                "is-stream": "1.1.0",
+                "npm-run-path": "2.0.2",
+                "p-finally": "1.0.0",
+                "signal-exit": "3.0.2",
+                "strip-eof": "1.0.0"
             },
             "dependencies": {
                 "cross-spawn": {
@@ -4670,9 +4670,9 @@
                     "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
                     "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
                     "requires": {
-                        "lru-cache": "^4.0.1",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "lru-cache": "4.1.5",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     }
                 }
             }
@@ -4687,7 +4687,7 @@
             "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
             "integrity": "sha1-YKYmaAdlQst+T1cZnUrG830sX0o=",
             "requires": {
-                "debug": "^2.2"
+                "debug": "2.6.9"
             }
         },
         "expand-brackets": {
@@ -4695,13 +4695,13 @@
             "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
             "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
             "requires": {
-                "debug": "^2.3.3",
-                "define-property": "^0.2.5",
-                "extend-shallow": "^2.0.1",
-                "posix-character-classes": "^0.1.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "debug": "2.6.9",
+                "define-property": "0.2.5",
+                "extend-shallow": "2.0.1",
+                "posix-character-classes": "0.1.1",
+                "regex-not": "1.0.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "define-property": {
@@ -4709,7 +4709,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "extend-shallow": {
@@ -4717,7 +4717,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -4733,7 +4733,7 @@
             "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
             "dev": true,
             "requires": {
-                "homedir-polyfill": "^1.0.1"
+                "homedir-polyfill": "1.0.3"
             }
         },
         "express": {
@@ -4741,36 +4741,36 @@
             "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
             "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
             "requires": {
-                "accepts": "~1.3.7",
+                "accepts": "1.3.7",
                 "array-flatten": "1.1.1",
                 "body-parser": "1.19.0",
                 "content-disposition": "0.5.3",
-                "content-type": "~1.0.4",
+                "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",
+                "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",
+                "methods": "1.1.2",
+                "on-finished": "2.3.0",
+                "parseurl": "1.3.3",
                 "path-to-regexp": "0.1.7",
-                "proxy-addr": "~2.0.5",
+                "proxy-addr": "2.0.5",
                 "qs": "6.7.0",
-                "range-parser": "~1.2.1",
+                "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",
+                "statuses": "1.5.0",
+                "type-is": "1.6.18",
                 "utils-merge": "1.0.1",
-                "vary": "~1.1.2"
+                "vary": "1.1.2"
             },
             "dependencies": {
                 "cookie": {
@@ -4785,7 +4785,7 @@
             "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
             "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
             "requires": {
-                "connect-flash": "0.1.x"
+                "connect-flash": "0.1.1"
             }
         },
         "express-session": {
@@ -4796,11 +4796,11 @@
                 "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",
+                "depd": "2.0.0",
+                "on-headers": "1.0.2",
+                "parseurl": "1.3.3",
                 "safe-buffer": "5.2.0",
-                "uid-safe": "~2.1.5"
+                "uid-safe": "2.1.5"
             },
             "dependencies": {
                 "cookie": {
@@ -4825,8 +4825,8 @@
             "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-5.3.1.tgz",
             "integrity": "sha512-g8xkipBF6VxHbO1+ksC7nxUU7+pWif0+OZXjZTybKJ/V0aTVhuCoHbyhIPgSYVldwQLocGExPtB2pE0DqK4jsw==",
             "requires": {
-                "lodash": "^4.17.10",
-                "validator": "^10.4.0"
+                "lodash": "4.17.15",
+                "validator": "10.11.0"
             }
         },
         "expressjs": {
@@ -4844,8 +4844,8 @@
             "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
             "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
             "requires": {
-                "assign-symbols": "^1.0.0",
-                "is-extendable": "^1.0.1"
+                "assign-symbols": "1.0.0",
+                "is-extendable": "1.0.1"
             },
             "dependencies": {
                 "is-extendable": {
@@ -4853,7 +4853,7 @@
                     "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
                     "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
                     "requires": {
-                        "is-plain-object": "^2.0.4"
+                        "is-plain-object": "2.0.4"
                     }
                 }
             }
@@ -4863,14 +4863,14 @@
             "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
             "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
             "requires": {
-                "array-unique": "^0.3.2",
-                "define-property": "^1.0.0",
-                "expand-brackets": "^2.1.4",
-                "extend-shallow": "^2.0.1",
-                "fragment-cache": "^0.2.1",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "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.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             },
             "dependencies": {
                 "define-property": {
@@ -4878,7 +4878,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "extend-shallow": {
@@ -4886,7 +4886,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -4894,7 +4894,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -4902,7 +4902,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -4910,9 +4910,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -4949,7 +4949,7 @@
             "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
             "dev": true,
             "requires": {
-                "websocket-driver": ">=0.5.1"
+                "websocket-driver": "0.7.3"
             }
         },
         "fbjs": {
@@ -4957,13 +4957,13 @@
             "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
             "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
             "requires": {
-                "core-js": "^1.0.0",
-                "isomorphic-fetch": "^2.1.1",
-                "loose-envify": "^1.0.0",
-                "object-assign": "^4.1.0",
-                "promise": "^7.1.1",
-                "setimmediate": "^1.0.5",
-                "ua-parser-js": "^0.7.18"
+                "core-js": "1.2.7",
+                "isomorphic-fetch": "2.2.1",
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "promise": "7.3.1",
+                "setimmediate": "1.0.5",
+                "ua-parser-js": "0.7.20"
             }
         },
         "figgy-pudding": {
@@ -4978,8 +4978,8 @@
             "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.0.2",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -4988,9 +4988,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -5007,7 +5007,7 @@
             "integrity": "sha1-9KGVc1Xdr0Q8zXiolfPVXiPIoDQ=",
             "dev": true,
             "requires": {
-                "debounce": "^1.0.0"
+                "debounce": "1.2.0"
             }
         },
         "fill-range": {
@@ -5015,10 +5015,10 @@
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
             "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
             "requires": {
-                "extend-shallow": "^2.0.1",
-                "is-number": "^3.0.0",
-                "repeat-string": "^1.6.1",
-                "to-regex-range": "^2.1.0"
+                "extend-shallow": "2.0.1",
+                "is-number": "3.0.0",
+                "repeat-string": "1.6.1",
+                "to-regex-range": "2.1.1"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -5026,7 +5026,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -5037,12 +5037,12 @@
             "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
             "requires": {
                 "debug": "2.6.9",
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "on-finished": "~2.3.0",
-                "parseurl": "~1.3.3",
-                "statuses": "~1.5.0",
-                "unpipe": "~1.0.0"
+                "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"
             }
         },
         "find": {
@@ -5050,7 +5050,7 @@
             "resolved": "https://registry.npmjs.org/find/-/find-0.1.7.tgz",
             "integrity": "sha1-yGyHrxqxjyIrvjjeyGy8dg0Wpvs=",
             "requires": {
-                "traverse-chain": "~0.1.0"
+                "traverse-chain": "0.1.0"
             }
         },
         "find-cache-dir": {
@@ -5059,9 +5059,9 @@
             "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
             "dev": true,
             "requires": {
-                "commondir": "^1.0.1",
-                "make-dir": "^1.0.0",
-                "pkg-dir": "^2.0.0"
+                "commondir": "1.0.1",
+                "make-dir": "1.3.0",
+                "pkg-dir": "2.0.0"
             }
         },
         "find-in-files": {
@@ -5069,8 +5069,8 @@
             "resolved": "https://registry.npmjs.org/find-in-files/-/find-in-files-0.5.0.tgz",
             "integrity": "sha512-VraTc6HdtdSHmAp0yJpAy20yPttGKzyBWc7b7FPnnsX9TOgmKx0g9xajizpF/iuu4IvNK4TP0SpyBT9zAlwG+g==",
             "requires": {
-                "find": "^0.1.5",
-                "q": "^1.0.1"
+                "find": "0.1.7",
+                "q": "1.5.1"
             }
         },
         "find-root": {
@@ -5083,7 +5083,7 @@
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
             "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
             "requires": {
-                "locate-path": "^2.0.0"
+                "locate-path": "2.0.0"
             }
         },
         "findup-sync": {
@@ -5092,10 +5092,10 @@
             "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
             "dev": true,
             "requires": {
-                "detect-file": "^1.0.0",
-                "is-glob": "^4.0.0",
-                "micromatch": "^3.0.4",
-                "resolve-dir": "^1.0.1"
+                "detect-file": "1.0.0",
+                "is-glob": "4.0.1",
+                "micromatch": "3.1.10",
+                "resolve-dir": "1.0.1"
             }
         },
         "flat": {
@@ -5103,7 +5103,7 @@
             "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
             "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
             "requires": {
-                "is-buffer": "~2.0.3"
+                "is-buffer": "2.0.4"
             },
             "dependencies": {
                 "is-buffer": {
@@ -5124,8 +5124,8 @@
             "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.3.6"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "follow-redirects": {
@@ -5134,7 +5134,7 @@
             "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==",
             "dev": true,
             "requires": {
-                "debug": "^3.0.0"
+                "debug": "3.2.6"
             },
             "dependencies": {
                 "debug": {
@@ -5143,7 +5143,7 @@
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -5164,7 +5164,7 @@
             "resolved": "https://registry.npmjs.org/for-each-property/-/for-each-property-0.0.4.tgz",
             "integrity": "sha1-z6hXrsFCLh0Sb/CHhPz2Jim8g/Y=",
             "requires": {
-                "get-prototype-chain": "^1.0.1"
+                "get-prototype-chain": "1.0.1"
             }
         },
         "for-each-property-deep": {
@@ -5191,14 +5191,14 @@
             "integrity": "sha512-vqOY5gakcoon2s12V7MMe01OPwfgqulUWFzm+geQaPPOBKjW1I7aqqoBVlU0ECn97liMB0ECs16pRdIGe9qdRw==",
             "dev": true,
             "requires": {
-                "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"
+                "babel-code-frame": "6.26.0",
+                "chalk": "2.4.2",
+                "chokidar": "2.1.8",
+                "micromatch": "3.1.10",
+                "minimatch": "3.0.4",
+                "semver": "5.7.0",
+                "tapable": "1.1.3",
+                "worker-rpc": "0.1.1"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -5207,7 +5207,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -5216,9 +5216,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -5227,7 +5227,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -5237,9 +5237,9 @@
             "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
             "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
             "requires": {
-                "asynckit": "^0.4.0",
-                "combined-stream": "^1.0.6",
-                "mime-types": "^2.1.12"
+                "asynckit": "0.4.0",
+                "combined-stream": "1.0.8",
+                "mime-types": "2.1.24"
             }
         },
         "formidable": {
@@ -5257,7 +5257,7 @@
             "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
             "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
             "requires": {
-                "map-cache": "^0.2.2"
+                "map-cache": "0.2.2"
             }
         },
         "fresh": {
@@ -5271,8 +5271,8 @@
             "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.0.0"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "fs-constants": {
@@ -5285,11 +5285,11 @@
             "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
             "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "jsonfile": "^2.1.0",
-                "klaw": "^1.0.0",
-                "path-is-absolute": "^1.0.0",
-                "rimraf": "^2.2.8"
+                "graceful-fs": "4.2.0",
+                "jsonfile": "2.4.0",
+                "klaw": "1.3.1",
+                "path-is-absolute": "1.0.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "rimraf": {
@@ -5297,7 +5297,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -5307,7 +5307,7 @@
             "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz",
             "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==",
             "requires": {
-                "minipass": "^2.2.1"
+                "minipass": "2.3.5"
             }
         },
         "fs-write-stream-atomic": {
@@ -5316,10 +5316,10 @@
             "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
             "dev": true,
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "iferr": "^0.1.5",
-                "imurmurhash": "^0.1.4",
-                "readable-stream": "1 || 2"
+                "graceful-fs": "4.2.0",
+                "iferr": "0.1.5",
+                "imurmurhash": "0.1.4",
+                "readable-stream": "2.3.6"
             }
         },
         "fs.realpath": {
@@ -5333,9 +5333,9 @@
             "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==",
             "optional": true,
             "requires": {
-                "bindings": "^1.5.0",
-                "nan": "^2.12.1",
-                "node-pre-gyp": "*"
+                "bindings": "1.5.0",
+                "nan": "2.14.0",
+                "node-pre-gyp": "0.14.0"
             },
             "dependencies": {
                 "abbrev": {
@@ -5345,8 +5345,7 @@
                 },
                 "ansi-regex": {
                     "version": "2.1.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "aproba": {
                     "version": "1.2.0",
@@ -5358,21 +5357,19 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "delegates": "^1.0.0",
-                        "readable-stream": "^2.0.6"
+                        "delegates": "1.0.0",
+                        "readable-stream": "2.3.6"
                     }
                 },
                 "balanced-match": {
                     "version": "1.0.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "brace-expansion": {
                     "version": "1.1.11",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "balanced-match": "^1.0.0",
+                        "balanced-match": "1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
@@ -5383,18 +5380,15 @@
                 },
                 "code-point-at": {
                     "version": "1.1.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "concat-map": {
                     "version": "0.0.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "console-control-strings": {
                     "version": "1.1.0",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "core-util-is": {
                     "version": "1.0.2",
@@ -5406,7 +5400,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "deep-extend": {
@@ -5429,7 +5423,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minipass": "^2.6.0"
+                        "minipass": "2.9.0"
                     }
                 },
                 "fs.realpath": {
@@ -5442,14 +5436,14 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "aproba": "^1.0.3",
-                        "console-control-strings": "^1.0.0",
-                        "has-unicode": "^2.0.0",
-                        "object-assign": "^4.1.0",
-                        "signal-exit": "^3.0.0",
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1",
-                        "wide-align": "^1.1.0"
+                        "aproba": "1.2.0",
+                        "console-control-strings": "1.1.0",
+                        "has-unicode": "2.0.1",
+                        "object-assign": "4.1.1",
+                        "signal-exit": "3.0.2",
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1",
+                        "wide-align": "1.1.3"
                     }
                 },
                 "glob": {
@@ -5457,12 +5451,12 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.4",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "has-unicode": {
@@ -5475,7 +5469,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "safer-buffer": ">= 2.1.2 < 3"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "ignore-walk": {
@@ -5483,7 +5477,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minimatch": "^3.0.4"
+                        "minimatch": "3.0.4"
                     }
                 },
                 "inflight": {
@@ -5491,14 +5485,13 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "once": "^1.3.0",
-                        "wrappy": "1"
+                        "once": "1.4.0",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "inherits": {
                     "version": "2.0.4",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "ini": {
                     "version": "1.3.5",
@@ -5508,9 +5501,8 @@
                 "is-fullwidth-code-point": {
                     "version": "1.0.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "number-is-nan": "^1.0.0"
+                        "number-is-nan": "1.0.1"
                     }
                 },
                 "isarray": {
@@ -5521,23 +5513,20 @@
                 "minimatch": {
                     "version": "3.0.4",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "brace-expansion": "^1.1.7"
+                        "brace-expansion": "1.1.11"
                     }
                 },
                 "minimist": {
                     "version": "0.0.8",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "minipass": {
                     "version": "2.9.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "safe-buffer": "^5.1.2",
-                        "yallist": "^3.0.0"
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.1.1"
                     }
                 },
                 "minizlib": {
@@ -5545,13 +5534,12 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "minipass": "^2.9.0"
+                        "minipass": "2.9.0"
                     }
                 },
                 "mkdirp": {
                     "version": "0.5.1",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
                         "minimist": "0.0.8"
                     }
@@ -5566,9 +5554,9 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "debug": "^3.2.6",
-                        "iconv-lite": "^0.4.4",
-                        "sax": "^1.2.4"
+                        "debug": "3.2.6",
+                        "iconv-lite": "0.4.24",
+                        "sax": "1.2.4"
                     }
                 },
                 "node-pre-gyp": {
@@ -5576,16 +5564,16 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "detect-libc": "^1.0.2",
-                        "mkdirp": "^0.5.1",
-                        "needle": "^2.2.1",
-                        "nopt": "^4.0.1",
-                        "npm-packlist": "^1.1.6",
-                        "npmlog": "^4.0.2",
-                        "rc": "^1.2.7",
-                        "rimraf": "^2.6.1",
-                        "semver": "^5.3.0",
-                        "tar": "^4.4.2"
+                        "detect-libc": "1.0.3",
+                        "mkdirp": "0.5.1",
+                        "needle": "2.4.0",
+                        "nopt": "4.0.1",
+                        "npm-packlist": "1.4.7",
+                        "npmlog": "4.1.2",
+                        "rc": "1.2.8",
+                        "rimraf": "2.7.1",
+                        "semver": "5.7.1",
+                        "tar": "4.4.13"
                     }
                 },
                 "nopt": {
@@ -5593,8 +5581,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "abbrev": "1",
-                        "osenv": "^0.1.4"
+                        "abbrev": "1.1.1",
+                        "osenv": "0.1.5"
                     }
                 },
                 "npm-bundled": {
@@ -5602,7 +5590,7 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "npm-normalize-package-bin": "^1.0.1"
+                        "npm-normalize-package-bin": "1.0.1"
                     }
                 },
                 "npm-normalize-package-bin": {
@@ -5615,8 +5603,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "ignore-walk": "^3.0.1",
-                        "npm-bundled": "^1.0.1"
+                        "ignore-walk": "3.0.3",
+                        "npm-bundled": "1.1.1"
                     }
                 },
                 "npmlog": {
@@ -5624,16 +5612,15 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "are-we-there-yet": "~1.1.2",
-                        "console-control-strings": "~1.1.0",
-                        "gauge": "~2.7.3",
-                        "set-blocking": "~2.0.0"
+                        "are-we-there-yet": "1.1.5",
+                        "console-control-strings": "1.1.0",
+                        "gauge": "2.7.4",
+                        "set-blocking": "2.0.0"
                     }
                 },
                 "number-is-nan": {
                     "version": "1.0.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "object-assign": {
                     "version": "4.1.1",
@@ -5643,9 +5630,8 @@
                 "once": {
                     "version": "1.4.0",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "wrappy": "1"
+                        "wrappy": "1.0.2"
                     }
                 },
                 "os-homedir": {
@@ -5663,8 +5649,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "os-homedir": "^1.0.0",
-                        "os-tmpdir": "^1.0.0"
+                        "os-homedir": "1.0.2",
+                        "os-tmpdir": "1.0.2"
                     }
                 },
                 "path-is-absolute": {
@@ -5682,10 +5668,10 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "deep-extend": "^0.6.0",
-                        "ini": "~1.3.0",
-                        "minimist": "^1.2.0",
-                        "strip-json-comments": "~2.0.1"
+                        "deep-extend": "0.6.0",
+                        "ini": "1.3.5",
+                        "minimist": "1.2.0",
+                        "strip-json-comments": "2.0.1"
                     },
                     "dependencies": {
                         "minimist": {
@@ -5700,13 +5686,13 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "core-util-is": "~1.0.0",
-                        "inherits": "~2.0.3",
-                        "isarray": "~1.0.0",
-                        "process-nextick-args": "~2.0.0",
-                        "safe-buffer": "~5.1.1",
-                        "string_decoder": "~1.1.1",
-                        "util-deprecate": "~1.0.1"
+                        "core-util-is": "1.0.2",
+                        "inherits": "2.0.4",
+                        "isarray": "1.0.0",
+                        "process-nextick-args": "2.0.1",
+                        "safe-buffer": "5.1.2",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "rimraf": {
@@ -5714,13 +5700,12 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.6"
                     }
                 },
                 "safe-buffer": {
                     "version": "5.1.2",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "safer-buffer": {
                     "version": "2.1.2",
@@ -5750,11 +5735,10 @@
                 "string-width": {
                     "version": "1.0.2",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "code-point-at": "^1.0.0",
-                        "is-fullwidth-code-point": "^1.0.0",
-                        "strip-ansi": "^3.0.0"
+                        "code-point-at": "1.1.0",
+                        "is-fullwidth-code-point": "1.0.0",
+                        "strip-ansi": "3.0.1"
                     }
                 },
                 "string_decoder": {
@@ -5762,15 +5746,14 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "strip-ansi": {
                     "version": "3.0.1",
                     "bundled": true,
-                    "optional": true,
                     "requires": {
-                        "ansi-regex": "^2.0.0"
+                        "ansi-regex": "2.1.1"
                     }
                 },
                 "strip-json-comments": {
@@ -5783,13 +5766,13 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "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"
+                        "chownr": "1.1.3",
+                        "fs-minipass": "1.2.7",
+                        "minipass": "2.9.0",
+                        "minizlib": "1.3.3",
+                        "mkdirp": "0.5.1",
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.1.1"
                     }
                 },
                 "util-deprecate": {
@@ -5802,18 +5785,16 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "string-width": "^1.0.2 || 2"
+                        "string-width": "1.0.2"
                     }
                 },
                 "wrappy": {
                     "version": "1.0.2",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 },
                 "yallist": {
                     "version": "3.1.1",
-                    "bundled": true,
-                    "optional": true
+                    "bundled": true
                 }
             }
         },
@@ -5822,10 +5803,10 @@
             "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
             "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "inherits": "~2.0.0",
-                "mkdirp": ">=0.5 0",
-                "rimraf": "2"
+                "graceful-fs": "4.2.0",
+                "inherits": "2.0.3",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1"
             },
             "dependencies": {
                 "rimraf": {
@@ -5833,7 +5814,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -5848,14 +5829,14 @@
             "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
             "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
             "requires": {
-                "aproba": "^1.0.3",
-                "console-control-strings": "^1.0.0",
-                "has-unicode": "^2.0.0",
-                "object-assign": "^4.1.0",
-                "signal-exit": "^3.0.0",
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1",
-                "wide-align": "^1.1.0"
+                "aproba": "1.2.0",
+                "console-control-strings": "1.1.0",
+                "has-unicode": "2.0.1",
+                "object-assign": "4.1.1",
+                "signal-exit": "3.0.2",
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1",
+                "wide-align": "1.1.3"
             }
         },
         "gaxios": {
@@ -5863,10 +5844,10 @@
             "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.0.1.tgz",
             "integrity": "sha512-c1NXovTxkgRJTIgB2FrFmOFg4YIV6N/bAa4f/FZ4jIw13Ql9ya/82x69CswvotJhbV3DiGnlTZwoq2NVXk2Irg==",
             "requires": {
-                "abort-controller": "^3.0.0",
-                "extend": "^3.0.2",
-                "https-proxy-agent": "^2.2.1",
-                "node-fetch": "^2.3.0"
+                "abort-controller": "3.0.0",
+                "extend": "3.0.2",
+                "https-proxy-agent": "2.2.2",
+                "node-fetch": "2.6.0"
             },
             "dependencies": {
                 "node-fetch": {
@@ -5881,7 +5862,7 @@
             "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
             "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
             "requires": {
-                "globule": "^1.0.0"
+                "globule": "1.3.0"
             }
         },
         "gcp-metadata": {
@@ -5889,8 +5870,8 @@
             "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-2.0.1.tgz",
             "integrity": "sha512-nrbLj5O1MurvpLC/doFwzdTfKnmYGDYXlY/v7eQ4tJNVIvQXbOK672J9UFbradbtmuTkyHzjpzD8HD0Djz0LWw==",
             "requires": {
-                "gaxios": "^2.0.0",
-                "json-bigint": "^0.3.0"
+                "gaxios": "2.0.1",
+                "json-bigint": "0.3.0"
             }
         },
         "get-caller-file": {
@@ -5933,7 +5914,7 @@
             "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
             "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
             "requires": {
-                "assert-plus": "^1.0.0"
+                "assert-plus": "1.0.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -5953,12 +5934,12 @@
             "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
             "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
             "requires": {
-                "fs.realpath": "^1.0.0",
-                "inflight": "^1.0.4",
-                "inherits": "2",
-                "minimatch": "^3.0.4",
-                "once": "^1.3.0",
-                "path-is-absolute": "^1.0.0"
+                "fs.realpath": "1.0.0",
+                "inflight": "1.0.6",
+                "inherits": "2.0.3",
+                "minimatch": "3.0.4",
+                "once": "1.4.0",
+                "path-is-absolute": "1.0.1"
             }
         },
         "glob-parent": {
@@ -5966,8 +5947,8 @@
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
             "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
             "requires": {
-                "is-glob": "^3.1.0",
-                "path-dirname": "^1.0.0"
+                "is-glob": "3.1.0",
+                "path-dirname": "1.0.2"
             },
             "dependencies": {
                 "is-glob": {
@@ -5975,7 +5956,7 @@
                     "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
                     "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
                     "requires": {
-                        "is-extglob": "^2.1.0"
+                        "is-extglob": "2.1.1"
                     }
                 }
             }
@@ -5985,7 +5966,7 @@
             "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
             "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
             "requires": {
-                "ini": "^1.3.4"
+                "ini": "1.3.5"
             }
         },
         "global-modules": {
@@ -5994,7 +5975,7 @@
             "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
             "dev": true,
             "requires": {
-                "global-prefix": "^3.0.0"
+                "global-prefix": "3.0.0"
             },
             "dependencies": {
                 "global-prefix": {
@@ -6003,9 +5984,9 @@
                     "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
                     "dev": true,
                     "requires": {
-                        "ini": "^1.3.5",
-                        "kind-of": "^6.0.2",
-                        "which": "^1.3.1"
+                        "ini": "1.3.5",
+                        "kind-of": "6.0.2",
+                        "which": "1.3.1"
                     }
                 }
             }
@@ -6016,11 +5997,11 @@
             "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
             "dev": true,
             "requires": {
-                "expand-tilde": "^2.0.2",
-                "homedir-polyfill": "^1.0.1",
-                "ini": "^1.3.4",
-                "is-windows": "^1.0.1",
-                "which": "^1.2.14"
+                "expand-tilde": "2.0.2",
+                "homedir-polyfill": "1.0.3",
+                "ini": "1.3.5",
+                "is-windows": "1.0.2",
+                "which": "1.3.1"
             }
         },
         "globby": {
@@ -6029,12 +6010,12 @@
             "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
             "dev": true,
             "requires": {
-                "array-union": "^1.0.1",
-                "dir-glob": "^2.0.0",
-                "glob": "^7.1.2",
-                "ignore": "^3.3.5",
-                "pify": "^3.0.0",
-                "slash": "^1.0.0"
+                "array-union": "1.0.2",
+                "dir-glob": "2.2.2",
+                "glob": "7.1.4",
+                "ignore": "3.3.10",
+                "pify": "3.0.0",
+                "slash": "1.0.0"
             },
             "dependencies": {
                 "pify": {
@@ -6050,9 +6031,9 @@
             "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz",
             "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==",
             "requires": {
-                "glob": "~7.1.1",
-                "lodash": "~4.17.10",
-                "minimatch": "~3.0.2"
+                "glob": "7.1.4",
+                "lodash": "4.17.15",
+                "minimatch": "3.0.4"
             }
         },
         "golden-layout": {
@@ -6060,7 +6041,7 @@
             "resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-1.5.9.tgz",
             "integrity": "sha1-o5vB9qZ+b4hreXwBbdkk6UJrp38=",
             "requires": {
-                "jquery": "*"
+                "jquery": "3.4.1"
             }
         },
         "google-auth-library": {
@@ -6068,14 +6049,14 @@
             "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-4.2.6.tgz",
             "integrity": "sha512-oJ6tCA9rbsYeIVY+mcLPFHa2hatz3XO6idYIrlI/KhhlMxZrO3tKyU8O2Pxu5KnSBBP7Wj4HtbM1LLKngNFaFw==",
             "requires": {
-                "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"
+                "arrify": "2.0.1",
+                "base64-js": "1.3.0",
+                "fast-text-encoding": "1.0.0",
+                "gaxios": "2.0.1",
+                "gcp-metadata": "2.0.1",
+                "gtoken": "3.0.2",
+                "jws": "3.2.2",
+                "lru-cache": "5.1.1"
             },
             "dependencies": {
                 "arrify": {
@@ -6088,7 +6069,7 @@
                     "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
                     "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 }
             }
@@ -6098,7 +6079,7 @@
             "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.1.tgz",
             "integrity": "sha512-6h6x+eBX3k+IDSe/c8dVYmn8Mzr1mUcmKC9MdUSwaBkFAXlqBEnwFWmSFgGC+tcqtsLn73BDP/vUNWEehf1Rww==",
             "requires": {
-                "node-forge": "^0.8.0"
+                "node-forge": "0.8.5"
             },
             "dependencies": {
                 "node-forge": {
@@ -6113,8 +6094,8 @@
             "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-40.0.1.tgz",
             "integrity": "sha512-B6qZVCautOOspEhru9GZ814I+ztkGWyA4ZEUfaXwXHBruX/HAWqedbsuUEx1w3nCECywK/FLTNUdcbH9zpaMaw==",
             "requires": {
-                "google-auth-library": "^4.0.0",
-                "googleapis-common": "^2.0.2"
+                "google-auth-library": "4.2.6",
+                "googleapis-common": "2.0.4"
             }
         },
         "googleapis-common": {
@@ -6122,12 +6103,12 @@
             "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-2.0.4.tgz",
             "integrity": "sha512-8RRkxr24v1jIKCC1onFWA8RGnwFV55m3Qpil9DLX1yLc9e5qvOJsRoDOhhD2e7jFRONYEhT/BzT8vJZANqSr9w==",
             "requires": {
-                "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"
+                "extend": "3.0.2",
+                "gaxios": "2.0.1",
+                "google-auth-library": "4.2.6",
+                "qs": "6.7.0",
+                "url-template": "2.0.8",
+                "uuid": "3.3.3"
             }
         },
         "googlephotos": {
@@ -6135,9 +6116,9 @@
             "resolved": "https://registry.npmjs.org/googlephotos/-/googlephotos-0.2.5.tgz",
             "integrity": "sha512-XPmD3gu8aMVuwauKVzzahD2Vn8Cn8WtBRGgSF5J9A85Fn6N2GM0OToxWbEoTfyKahK+ryGHGcIYzDX98ndxE9g==",
             "requires": {
-                "lodash.chunk": "^4.2.0",
-                "request": "^2.86.0",
-                "request-promise": "^4.2.2"
+                "lodash.chunk": "4.2.0",
+                "request": "2.88.0",
+                "request-promise": "4.2.5"
             }
         },
         "got": {
@@ -6145,17 +6126,17 @@
             "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz",
             "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
             "requires": {
-                "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"
+                "create-error-class": "3.0.2",
+                "duplexer3": "0.1.4",
+                "get-stream": "3.0.0",
+                "is-redirect": "1.0.0",
+                "is-retry-allowed": "1.2.0",
+                "is-stream": "1.1.0",
+                "lowercase-keys": "1.0.1",
+                "safe-buffer": "5.1.2",
+                "timed-out": "4.0.1",
+                "unzip-response": "2.0.1",
+                "url-parse-lax": "1.0.0"
             }
         },
         "graceful-fs": {
@@ -6179,10 +6160,10 @@
             "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-3.0.2.tgz",
             "integrity": "sha512-BOBi6Zz31JfxhSHRZBIDdbwIbOPyux10WxJHdx8wz/FMP1zyN1xFrsAWsgcLe5ww5v/OZu/MePUEZAjgJXSauA==",
             "requires": {
-                "gaxios": "^2.0.0",
-                "google-p12-pem": "^2.0.0",
-                "jws": "^3.1.5",
-                "mime": "^2.2.0"
+                "gaxios": "2.0.1",
+                "google-p12-pem": "2.0.1",
+                "jws": "3.2.2",
+                "mime": "2.4.4"
             },
             "dependencies": {
                 "mime": {
@@ -6213,8 +6194,8 @@
             "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
             "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
             "requires": {
-                "ajv": "^6.5.5",
-                "har-schema": "^2.0.0"
+                "ajv": "6.10.2",
+                "har-schema": "2.0.0"
             }
         },
         "has": {
@@ -6222,7 +6203,7 @@
             "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
             "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
             "requires": {
-                "function-bind": "^1.1.1"
+                "function-bind": "1.1.1"
             }
         },
         "has-ansi": {
@@ -6230,7 +6211,7 @@
             "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
             "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
             "requires": {
-                "ansi-regex": "^2.0.0"
+                "ansi-regex": "2.1.1"
             }
         },
         "has-binary2": {
@@ -6273,9 +6254,9 @@
             "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
             "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
             "requires": {
-                "get-value": "^2.0.6",
-                "has-values": "^1.0.0",
-                "isobject": "^3.0.0"
+                "get-value": "2.0.6",
+                "has-values": "1.0.0",
+                "isobject": "3.0.1"
             }
         },
         "has-values": {
@@ -6283,8 +6264,8 @@
             "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
             "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
             "requires": {
-                "is-number": "^3.0.0",
-                "kind-of": "^4.0.0"
+                "is-number": "3.0.0",
+                "kind-of": "4.0.0"
             },
             "dependencies": {
                 "kind-of": {
@@ -6292,7 +6273,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
                     "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -6302,8 +6283,8 @@
             "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
             "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "hash.js": {
@@ -6311,8 +6292,8 @@
             "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
             "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
             "requires": {
-                "inherits": "^2.0.3",
-                "minimalistic-assert": "^1.0.1"
+                "inherits": "2.0.3",
+                "minimalistic-assert": "1.0.1"
             }
         },
         "he": {
@@ -6326,9 +6307,9 @@
             "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
             "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
             "requires": {
-                "hash.js": "^1.0.3",
-                "minimalistic-assert": "^1.0.0",
-                "minimalistic-crypto-utils": "^1.0.1"
+                "hash.js": "1.1.7",
+                "minimalistic-assert": "1.0.1",
+                "minimalistic-crypto-utils": "1.0.1"
             }
         },
         "hoist-non-react-statics": {
@@ -6336,7 +6317,7 @@
             "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz",
             "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==",
             "requires": {
-                "react-is": "^16.7.0"
+                "react-is": "16.8.6"
             }
         },
         "homedir-polyfill": {
@@ -6345,7 +6326,7 @@
             "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
             "dev": true,
             "requires": {
-                "parse-passwd": "^1.0.0"
+                "parse-passwd": "1.0.0"
             }
         },
         "hosted-git-info": {
@@ -6364,10 +6345,10 @@
             "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
             "dev": true,
             "requires": {
-                "inherits": "^2.0.1",
-                "obuf": "^1.0.0",
-                "readable-stream": "^2.0.1",
-                "wbuf": "^1.1.0"
+                "inherits": "2.0.3",
+                "obuf": "1.1.2",
+                "readable-stream": "2.3.6",
+                "wbuf": "1.7.3"
             }
         },
         "html-encoding-sniffer": {
@@ -6376,7 +6357,7 @@
             "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
             "dev": true,
             "requires": {
-                "whatwg-encoding": "^1.0.1"
+                "whatwg-encoding": "1.0.5"
             }
         },
         "html-entities": {
@@ -6395,12 +6376,12 @@
             "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
             "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
             "requires": {
-                "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"
+                "domelementtype": "1.3.1",
+                "domhandler": "2.4.2",
+                "domutils": "1.5.1",
+                "entities": "1.1.2",
+                "inherits": "2.0.3",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -6408,9 +6389,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -6426,10 +6407,10 @@
             "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
             "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
             "requires": {
-                "depd": "~1.1.2",
+                "depd": "1.1.2",
                 "inherits": "2.0.3",
                 "setprototypeof": "1.1.1",
-                "statuses": ">= 1.5.0 < 2",
+                "statuses": "1.5.0",
                 "toidentifier": "1.0.0"
             }
         },
@@ -6445,9 +6426,9 @@
             "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
             "dev": true,
             "requires": {
-                "eventemitter3": "^4.0.0",
-                "follow-redirects": "^1.0.0",
-                "requires-port": "^1.0.0"
+                "eventemitter3": "4.0.0",
+                "follow-redirects": "1.9.0",
+                "requires-port": "1.0.0"
             },
             "dependencies": {
                 "eventemitter3": {
@@ -6464,10 +6445,10 @@
             "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
             "dev": true,
             "requires": {
-                "http-proxy": "^1.17.0",
-                "is-glob": "^4.0.0",
-                "lodash": "^4.17.11",
-                "micromatch": "^3.1.10"
+                "http-proxy": "1.18.0",
+                "is-glob": "4.0.1",
+                "lodash": "4.17.15",
+                "micromatch": "3.1.10"
             }
         },
         "http-signature": {
@@ -6475,9 +6456,9 @@
             "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
             "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
             "requires": {
-                "assert-plus": "^1.0.0",
-                "jsprim": "^1.2.2",
-                "sshpk": "^1.7.0"
+                "assert-plus": "1.0.0",
+                "jsprim": "1.4.1",
+                "sshpk": "1.16.1"
             }
         },
         "https-browserify": {
@@ -6491,8 +6472,8 @@
             "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
             "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
             "requires": {
-                "agent-base": "^4.3.0",
-                "debug": "^3.1.0"
+                "agent-base": "4.3.0",
+                "debug": "3.2.6"
             },
             "dependencies": {
                 "debug": {
@@ -6500,7 +6481,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -6520,7 +6501,7 @@
             "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
             "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
             "requires": {
-                "safer-buffer": ">= 2.1.2 < 3"
+                "safer-buffer": "2.1.2"
             }
         },
         "icss-replace-symbols": {
@@ -6535,7 +6516,7 @@
             "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.14"
+                "postcss": "7.0.17"
             }
         },
         "ieee754": {
@@ -6565,7 +6546,7 @@
             "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
             "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
             "requires": {
-                "minimatch": "^3.0.4"
+                "minimatch": "3.0.4"
             }
         },
         "image-data-uri": {
@@ -6573,10 +6554,10 @@
             "resolved": "https://registry.npmjs.org/image-data-uri/-/image-data-uri-2.0.1.tgz",
             "integrity": "sha512-BZh721F2Q5TwBdwpiqrBrHEdj8daj8KuMZK/DOCyqQlz1CqFhhuZWbK5ZCUnAvFJr8LaKHTaWl9ja3/a3DC2Ew==",
             "requires": {
-                "fs-extra": "^0.26.7",
+                "fs-extra": "0.26.7",
                 "magicli": "0.0.8",
-                "mime-types": "^2.1.18",
-                "request": "^2.88.0"
+                "mime-types": "2.1.24",
+                "request": "2.88.0"
             }
         },
         "image-size": {
@@ -6589,7 +6570,7 @@
             "resolved": "https://registry.npmjs.org/imagesloaded/-/imagesloaded-4.1.4.tgz",
             "integrity": "sha512-ltiBVcYpc/TYTF5nolkMNsnREHW+ICvfQ3Yla2Sgr71YFwQ86bDwV9hgpFhFtrGPuwEx5+LqOHIrdXBdoWwwsA==",
             "requires": {
-                "ev-emitter": "^1.0.0"
+                "ev-emitter": "1.1.1"
             }
         },
         "immutable": {
@@ -6602,8 +6583,8 @@
             "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
             "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
             "requires": {
-                "parent-module": "^1.0.0",
-                "resolve-from": "^4.0.0"
+                "parent-module": "1.0.1",
+                "resolve-from": "4.0.0"
             },
             "dependencies": {
                 "resolve-from": {
@@ -6624,8 +6605,8 @@
             "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
             "dev": true,
             "requires": {
-                "pkg-dir": "^3.0.0",
-                "resolve-cwd": "^2.0.0"
+                "pkg-dir": "3.0.0",
+                "resolve-cwd": "2.0.0"
             },
             "dependencies": {
                 "find-up": {
@@ -6634,7 +6615,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "locate-path": {
@@ -6643,8 +6624,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "p-locate": {
@@ -6653,7 +6634,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "pkg-dir": {
@@ -6662,7 +6643,7 @@
                     "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
                     "dev": true,
                     "requires": {
-                        "find-up": "^3.0.0"
+                        "find-up": "3.0.0"
                     }
                 }
             }
@@ -6682,7 +6663,7 @@
             "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
             "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
             "requires": {
-                "repeating": "^2.0.0"
+                "repeating": "2.0.1"
             }
         },
         "indexes-of": {
@@ -6707,8 +6688,8 @@
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
             "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
             "requires": {
-                "once": "^1.3.0",
-                "wrappy": "1"
+                "once": "1.4.0",
+                "wrappy": "1.0.2"
             }
         },
         "infobox-parser": {
@@ -6716,7 +6697,7 @@
             "resolved": "https://registry.npmjs.org/infobox-parser/-/infobox-parser-3.3.1.tgz",
             "integrity": "sha512-Aj1uF/taawGhet8cazhXz2uEDFMOqH8hnuw720wvi7Zw6bJWmA45Ta2FI9xMG5wvvo4CB6GR9S1/RUFtC6EtAg==",
             "requires": {
-                "camelcase": "^4.1.0"
+                "camelcase": "4.1.0"
             }
         },
         "inherits": {
@@ -6761,10 +6742,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -6776,7 +6757,7 @@
             "requires": {
                 "for-each-property": "0.0.4",
                 "for-each-property-deep": "0.0.3",
-                "inspect-function": "^0.3.1"
+                "inspect-function": "0.3.4"
             },
             "dependencies": {
                 "inspect-function": {
@@ -6823,10 +6804,10 @@
                             "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                             "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                             "requires": {
-                                "commander": "^2.9.0",
-                                "get-stdin": "^5.0.1",
-                                "inspect-function": "^0.2.1",
-                                "pipe-functions": "^1.2.0"
+                                "commander": "2.20.0",
+                                "get-stdin": "5.0.1",
+                                "inspect-function": "0.2.2",
+                                "pipe-functions": "1.3.0"
                             }
                         },
                         "split-skip": {
@@ -6849,8 +6830,8 @@
             "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
             "dev": true,
             "requires": {
-                "default-gateway": "^4.2.0",
-                "ipaddr.js": "^1.9.0"
+                "default-gateway": "4.2.0",
+                "ipaddr.js": "1.9.0"
             }
         },
         "interpret": {
@@ -6863,7 +6844,7 @@
             "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
             "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
             "requires": {
-                "loose-envify": "^1.0.0"
+                "loose-envify": "1.4.0"
             }
         },
         "invert-kv": {
@@ -6896,10 +6877,10 @@
         },
         "is-accessor-descriptor": {
             "version": "0.1.6",
-            "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+            "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
             "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -6907,7 +6888,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -6928,7 +6909,7 @@
             "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
             "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
             "requires": {
-                "binary-extensions": "^1.0.0"
+                "binary-extensions": "1.13.1"
             }
         },
         "is-buffer": {
@@ -6946,15 +6927,15 @@
             "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
             "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
             "requires": {
-                "ci-info": "^1.5.0"
+                "ci-info": "1.6.0"
             }
         },
         "is-data-descriptor": {
             "version": "0.1.4",
-            "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+            "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
             "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -6962,7 +6943,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -6977,9 +6958,9 @@
             "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
             "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
             "requires": {
-                "is-accessor-descriptor": "^0.1.6",
-                "is-data-descriptor": "^0.1.4",
-                "kind-of": "^5.0.0"
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
             },
             "dependencies": {
                 "kind-of": {
@@ -6994,8 +6975,8 @@
             "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
             "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
             "requires": {
-                "acorn": "~4.0.2",
-                "object-assign": "^4.0.1"
+                "acorn": "4.0.13",
+                "object-assign": "4.1.1"
             },
             "dependencies": {
                 "acorn": {
@@ -7020,7 +7001,7 @@
             "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
             "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
             "requires": {
-                "number-is-nan": "^1.0.0"
+                "number-is-nan": "1.0.1"
             }
         },
         "is-fullwidth-code-point": {
@@ -7028,7 +7009,7 @@
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
             "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
             "requires": {
-                "number-is-nan": "^1.0.0"
+                "number-is-nan": "1.0.1"
             }
         },
         "is-glob": {
@@ -7036,7 +7017,7 @@
             "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
             "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
             "requires": {
-                "is-extglob": "^2.1.1"
+                "is-extglob": "2.1.1"
             }
         },
         "is-installed-globally": {
@@ -7044,8 +7025,8 @@
             "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
             "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
             "requires": {
-                "global-dirs": "^0.1.0",
-                "is-path-inside": "^1.0.0"
+                "global-dirs": "0.1.1",
+                "is-path-inside": "1.0.1"
             }
         },
         "is-npm": {
@@ -7058,7 +7039,7 @@
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
             "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -7066,7 +7047,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -7088,7 +7069,7 @@
             "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
             "dev": true,
             "requires": {
-                "is-path-inside": "^2.1.0"
+                "is-path-inside": "2.1.0"
             },
             "dependencies": {
                 "is-path-inside": {
@@ -7097,7 +7078,7 @@
                     "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
                     "dev": true,
                     "requires": {
-                        "path-is-inside": "^1.0.2"
+                        "path-is-inside": "1.0.2"
                     }
                 }
             }
@@ -7107,7 +7088,7 @@
             "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
             "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
             "requires": {
-                "path-is-inside": "^1.0.1"
+                "path-is-inside": "1.0.2"
             }
         },
         "is-plain-object": {
@@ -7115,7 +7096,7 @@
             "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
             "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
             "requires": {
-                "isobject": "^3.0.1"
+                "isobject": "3.0.1"
             }
         },
         "is-promise": {
@@ -7133,7 +7114,7 @@
             "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
             "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
             "requires": {
-                "has": "^1.0.1"
+                "has": "1.0.3"
             }
         },
         "is-retry-allowed": {
@@ -7151,7 +7132,7 @@
             "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
             "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
             "requires": {
-                "has-symbols": "^1.0.0"
+                "has-symbols": "1.0.0"
             }
         },
         "is-typedarray": {
@@ -7195,8 +7176,8 @@
             "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
             "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
             "requires": {
-                "node-fetch": "^1.0.1",
-                "whatwg-fetch": ">=0.10.0"
+                "node-fetch": "1.7.3",
+                "whatwg-fetch": "3.0.0"
             }
         },
         "isstream": {
@@ -7209,8 +7190,8 @@
             "resolved": "https://registry.npmjs.org/its-set/-/its-set-1.2.3.tgz",
             "integrity": "sha512-UQc+xLLn+0a8KKRXRj3OS2kERK8G7zcayPpPULqZnPwuJ1hGWEO8+j0T5eycu7DKXYjezw3pyF8oV1fJkJxV5w==",
             "requires": {
-                "babel-runtime": "6.x.x",
-                "lodash.get": "^4.4.2"
+                "babel-runtime": "6.26.0",
+                "lodash.get": "4.4.2"
             }
         },
         "jquery": {
@@ -7223,7 +7204,7 @@
             "resolved": "https://registry.npmjs.org/jquery-awesome-cursor/-/jquery-awesome-cursor-0.3.1.tgz",
             "integrity": "sha1-1pcaMrRiRhC868rAkDsAFWHQXso=",
             "requires": {
-                "font-awesome": "4.x"
+                "font-awesome": "4.7.0"
             }
         },
         "js-base64": {
@@ -7251,8 +7232,8 @@
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
             "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
             "requires": {
-                "argparse": "^1.0.7",
-                "esprima": "^4.0.0"
+                "argparse": "1.0.10",
+                "esprima": "4.0.1"
             }
         },
         "jsbn": {
@@ -7266,32 +7247,32 @@
             "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
             "dev": true,
             "requires": {
-                "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",
+                "abab": "2.0.3",
+                "acorn": "7.1.0",
+                "acorn-globals": "4.3.4",
+                "array-equal": "1.0.0",
+                "cssom": "0.4.4",
+                "cssstyle": "2.0.0",
+                "data-urls": "1.1.0",
+                "domexception": "1.0.1",
+                "escodegen": "1.12.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"
+                "pn": "1.1.0",
+                "request": "2.88.0",
+                "request-promise-native": "1.0.8",
+                "saxes": "3.1.11",
+                "symbol-tree": "3.2.4",
+                "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.1.0",
+                "ws": "7.2.1",
+                "xml-name-validator": "3.0.0"
             },
             "dependencies": {
                 "acorn": {
@@ -7306,8 +7287,8 @@
                     "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
                     "dev": true,
                     "requires": {
-                        "acorn": "^6.0.1",
-                        "acorn-walk": "^6.0.1"
+                        "acorn": "6.4.0",
+                        "acorn-walk": "6.2.0"
                     },
                     "dependencies": {
                         "acorn": {
@@ -7324,9 +7305,9 @@
                     "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
                     "dev": true,
                     "requires": {
-                        "ip-regex": "^2.1.0",
-                        "psl": "^1.1.28",
-                        "punycode": "^2.1.1"
+                        "ip-regex": "2.1.0",
+                        "psl": "1.2.0",
+                        "punycode": "2.1.1"
                     }
                 }
             }
@@ -7336,7 +7317,7 @@
             "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
             "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
             "requires": {
-                "bignumber.js": "^7.0.0"
+                "bignumber.js": "7.2.1"
             }
         },
         "json-parse-better-errors": {
@@ -7375,7 +7356,7 @@
             "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
             "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
             "requires": {
-                "minimist": "^1.2.0"
+                "minimist": "1.2.0"
             },
             "dependencies": {
                 "minimist": {
@@ -7390,7 +7371,7 @@
             "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
             "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
             "requires": {
-                "graceful-fs": "^4.1.6"
+                "graceful-fs": "4.2.0"
             }
         },
         "jsonschema": {
@@ -7403,16 +7384,16 @@
             "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
             "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
             "requires": {
-                "jws": "^3.2.2",
-                "lodash.includes": "^4.3.0",
-                "lodash.isboolean": "^3.0.3",
-                "lodash.isinteger": "^4.0.4",
-                "lodash.isnumber": "^3.0.3",
-                "lodash.isplainobject": "^4.0.6",
-                "lodash.isstring": "^4.0.1",
-                "lodash.once": "^4.0.0",
-                "ms": "^2.1.1",
-                "semver": "^5.6.0"
+                "jws": "3.2.2",
+                "lodash.includes": "4.3.0",
+                "lodash.isboolean": "3.0.3",
+                "lodash.isinteger": "4.0.4",
+                "lodash.isnumber": "3.0.3",
+                "lodash.isplainobject": "4.0.6",
+                "lodash.isstring": "4.0.1",
+                "lodash.once": "4.1.1",
+                "ms": "2.1.2",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "ms": {
@@ -7445,11 +7426,11 @@
             "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz",
             "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=",
             "requires": {
-                "base62": "^1.1.0",
-                "commoner": "^0.10.1",
-                "esprima-fb": "^15001.1.0-dev-harmony-fb",
-                "object-assign": "^2.0.0",
-                "source-map": "^0.4.2"
+                "base62": "1.2.8",
+                "commoner": "0.10.8",
+                "esprima-fb": "15001.1.0-dev-harmony-fb",
+                "object-assign": "2.1.1",
+                "source-map": "0.4.4"
             },
             "dependencies": {
                 "esprima-fb": {
@@ -7467,7 +7448,7 @@
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
                     "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
                     "requires": {
-                        "amdefine": ">=0.0.4"
+                        "amdefine": "1.0.1"
                     }
                 }
             }
@@ -7477,8 +7458,8 @@
             "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
             "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
             "requires": {
-                "is-promise": "^2.0.0",
-                "promise": "^7.0.1"
+                "is-promise": "2.1.0",
+                "promise": "7.3.1"
             }
         },
         "jsx-to-string": {
@@ -7486,9 +7467,9 @@
             "resolved": "https://registry.npmjs.org/jsx-to-string/-/jsx-to-string-1.4.0.tgz",
             "integrity": "sha1-Ztw013PaufQP6ZPP+ZQOXaZVtwU=",
             "requires": {
-                "immutable": "^4.0.0-rc.9",
-                "json-stringify-pretty-compact": "^1.0.1",
-                "react": "^0.14.0"
+                "immutable": "4.0.0-rc.12",
+                "json-stringify-pretty-compact": "1.2.0",
+                "react": "0.14.9"
             },
             "dependencies": {
                 "fbjs": {
@@ -7496,11 +7477,11 @@
                     "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.6.1.tgz",
                     "integrity": "sha1-lja3cF9bqWhNRLcveDISVK/IYPc=",
                     "requires": {
-                        "core-js": "^1.0.0",
-                        "loose-envify": "^1.0.0",
-                        "promise": "^7.0.3",
-                        "ua-parser-js": "^0.7.9",
-                        "whatwg-fetch": "^0.9.0"
+                        "core-js": "1.2.7",
+                        "loose-envify": "1.4.0",
+                        "promise": "7.3.1",
+                        "ua-parser-js": "0.7.20",
+                        "whatwg-fetch": "0.9.0"
                     }
                 },
                 "react": {
@@ -7508,8 +7489,8 @@
                     "resolved": "https://registry.npmjs.org/react/-/react-0.14.9.tgz",
                     "integrity": "sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=",
                     "requires": {
-                        "envify": "^3.0.0",
-                        "fbjs": "^0.6.1"
+                        "envify": "3.4.1",
+                        "fbjs": "0.6.1"
                     }
                 },
                 "whatwg-fetch": {
@@ -7526,7 +7507,7 @@
             "requires": {
                 "buffer-equal-constant-time": "1.0.1",
                 "ecdsa-sig-formatter": "1.0.11",
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "jws": {
@@ -7534,8 +7515,8 @@
             "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
             "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
             "requires": {
-                "jwa": "^1.4.1",
-                "safe-buffer": "^5.0.1"
+                "jwa": "1.4.1",
+                "safe-buffer": "5.1.2"
             }
         },
         "kareem": {
@@ -7569,7 +7550,7 @@
             "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
             "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
             "requires": {
-                "graceful-fs": "^4.1.9"
+                "graceful-fs": "4.2.0"
             }
         },
         "latest-version": {
@@ -7577,7 +7558,7 @@
             "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
             "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
             "requires": {
-                "package-json": "^4.0.0"
+                "package-json": "4.0.1"
             }
         },
         "lazy-cache": {
@@ -7590,7 +7571,7 @@
             "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
             "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
             "requires": {
-                "readable-stream": "^2.0.5"
+                "readable-stream": "2.3.6"
             }
         },
         "lcid": {
@@ -7598,7 +7579,7 @@
             "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
             "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
             "requires": {
-                "invert-kv": "^1.0.0"
+                "invert-kv": "1.0.0"
             }
         },
         "levn": {
@@ -7607,8 +7588,8 @@
             "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
             "dev": true,
             "requires": {
-                "prelude-ls": "~1.1.2",
-                "type-check": "~0.3.2"
+                "prelude-ls": "1.1.2",
+                "type-check": "0.3.2"
             }
         },
         "lines-and-columns": {
@@ -7618,14 +7599,14 @@
         },
         "load-json-file": {
             "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
             "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "parse-json": "^2.2.0",
-                "pify": "^2.0.0",
-                "pinkie-promise": "^2.0.0",
-                "strip-bom": "^2.0.0"
+                "graceful-fs": "4.2.0",
+                "parse-json": "2.2.0",
+                "pify": "2.3.0",
+                "pinkie-promise": "2.0.1",
+                "strip-bom": "2.0.0"
             },
             "dependencies": {
                 "parse-json": {
@@ -7633,7 +7614,7 @@
                     "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
                     "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
                     "requires": {
-                        "error-ex": "^1.2.0"
+                        "error-ex": "1.3.2"
                     }
                 }
             }
@@ -7649,9 +7630,9 @@
             "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz",
             "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==",
             "requires": {
-                "big.js": "^5.2.2",
-                "emojis-list": "^2.0.0",
-                "json5": "^1.0.1"
+                "big.js": "5.2.2",
+                "emojis-list": "2.1.0",
+                "json5": "1.0.1"
             }
         },
         "locate-path": {
@@ -7659,8 +7640,8 @@
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
             "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
             "requires": {
-                "p-locate": "^2.0.0",
-                "path-exists": "^3.0.0"
+                "p-locate": "2.0.0",
+                "path-exists": "3.0.0"
             }
         },
         "lodash": {
@@ -7759,7 +7740,7 @@
             "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
             "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
             "requires": {
-                "chalk": "^2.0.1"
+                "chalk": "2.4.2"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -7767,7 +7748,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -7775,9 +7756,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -7785,7 +7766,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -7802,8 +7783,8 @@
             "integrity": "sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==",
             "dev": true,
             "requires": {
-                "es6-symbol": "^3.1.1",
-                "object.assign": "^4.1.0"
+                "es6-symbol": "3.1.1",
+                "object.assign": "4.1.0"
             }
         },
         "longest": {
@@ -7816,7 +7797,7 @@
             "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
             "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
             "requires": {
-                "js-tokens": "^3.0.0 || ^4.0.0"
+                "js-tokens": "4.0.0"
             }
         },
         "loud-rejection": {
@@ -7824,8 +7805,8 @@
             "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
             "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
             "requires": {
-                "currently-unhandled": "^0.4.1",
-                "signal-exit": "^3.0.0"
+                "currently-unhandled": "0.4.1",
+                "signal-exit": "3.0.2"
             }
         },
         "lowercase-keys": {
@@ -7838,8 +7819,8 @@
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
             "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
             "requires": {
-                "pseudomap": "^1.0.2",
-                "yallist": "^2.1.2"
+                "pseudomap": "1.0.2",
+                "yallist": "2.1.2"
             },
             "dependencies": {
                 "yallist": {
@@ -7855,7 +7836,7 @@
             "integrity": "sha512-x/eBenweAHF+DsYy172sK4doRxZl0yrJnfxhLJiN7H6hPM3Ya0PfI6uBZshZ3ScFFSQD7HXgBqMdbnXKEZsO1g==",
             "requires": {
                 "cliss": "0.0.2",
-                "find-up": "^2.1.0",
+                "find-up": "2.1.0",
                 "for-each-property": "0.0.4",
                 "inspect-property": "0.0.6"
             }
@@ -7865,7 +7846,7 @@
             "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
             "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
             "requires": {
-                "pify": "^3.0.0"
+                "pify": "3.0.0"
             },
             "dependencies": {
                 "pify": {
@@ -7893,7 +7874,7 @@
             "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
             "dev": true,
             "requires": {
-                "p-defer": "^1.0.0"
+                "p-defer": "1.0.0"
             }
         },
         "map-cache": {
@@ -7911,7 +7892,7 @@
             "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
             "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
             "requires": {
-                "object-visit": "^1.0.0"
+                "object-visit": "1.0.1"
             }
         },
         "material-colors": {
@@ -7924,14 +7905,14 @@
             "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
             "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
             "requires": {
-                "hash-base": "^3.0.0",
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "hash-base": "3.0.4",
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "media-typer": {
             "version": "0.3.0",
-            "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+            "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
             "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
         },
         "mem": {
@@ -7940,9 +7921,9 @@
             "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
             "dev": true,
             "requires": {
-                "map-age-cleaner": "^0.1.1",
-                "mimic-fn": "^2.0.0",
-                "p-is-promise": "^2.0.0"
+                "map-age-cleaner": "0.1.3",
+                "mimic-fn": "2.1.0",
+                "p-is-promise": "2.1.0"
             }
         },
         "memory-fs": {
@@ -7951,8 +7932,8 @@
             "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
             "dev": true,
             "requires": {
-                "errno": "^0.1.3",
-                "readable-stream": "^2.0.1"
+                "errno": "0.1.7",
+                "readable-stream": "2.3.6"
             }
         },
         "memory-pager": {
@@ -7963,19 +7944,19 @@
         },
         "meow": {
             "version": "3.7.0",
-            "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+            "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
             "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
             "requires": {
-                "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"
+                "camelcase-keys": "2.1.0",
+                "decamelize": "1.2.0",
+                "loud-rejection": "1.6.0",
+                "map-obj": "1.0.1",
+                "minimist": "1.2.0",
+                "normalize-package-data": "2.5.0",
+                "object-assign": "4.1.1",
+                "read-pkg-up": "1.0.1",
+                "redent": "1.0.0",
+                "trim-newlines": "1.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -8006,19 +7987,19 @@
             "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
             "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
             "requires": {
-                "arr-diff": "^4.0.0",
-                "array-unique": "^0.3.2",
-                "braces": "^2.3.1",
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "extglob": "^2.0.4",
-                "fragment-cache": "^0.2.1",
-                "kind-of": "^6.0.2",
-                "nanomatch": "^1.2.9",
-                "object.pick": "^1.3.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.2"
+                "arr-diff": "4.0.0",
+                "array-unique": "0.3.2",
+                "braces": "2.3.2",
+                "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.13",
+                "object.pick": "1.3.0",
+                "regex-not": "1.0.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             }
         },
         "miller-rabin": {
@@ -8026,8 +8007,8 @@
             "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
             "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
             "requires": {
-                "bn.js": "^4.0.0",
-                "brorand": "^1.0.1"
+                "bn.js": "4.11.8",
+                "brorand": "1.1.0"
             }
         },
         "mime": {
@@ -8074,7 +8055,7 @@
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
             "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
             "requires": {
-                "brace-expansion": "^1.1.7"
+                "brace-expansion": "1.1.11"
             }
         },
         "minimist": {
@@ -8087,8 +8068,8 @@
             "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
             "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
             "requires": {
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.0"
+                "safe-buffer": "5.1.2",
+                "yallist": "3.0.3"
             }
         },
         "minizlib": {
@@ -8096,7 +8077,7 @@
             "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
             "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
             "requires": {
-                "minipass": "^2.2.1"
+                "minipass": "2.3.5"
             }
         },
         "mississippi": {
@@ -8105,16 +8086,16 @@
             "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
             "dev": true,
             "requires": {
-                "concat-stream": "^1.5.0",
-                "duplexify": "^3.4.2",
-                "end-of-stream": "^1.1.0",
-                "flush-write-stream": "^1.0.0",
-                "from2": "^2.1.0",
-                "parallel-transform": "^1.1.0",
-                "pump": "^2.0.1",
-                "pumpify": "^1.3.3",
-                "stream-each": "^1.1.0",
-                "through2": "^2.0.0"
+                "concat-stream": "1.6.2",
+                "duplexify": "3.7.1",
+                "end-of-stream": "1.4.1",
+                "flush-write-stream": "1.1.1",
+                "from2": "2.3.0",
+                "parallel-transform": "1.1.0",
+                "pump": "2.0.1",
+                "pumpify": "1.5.1",
+                "stream-each": "1.2.3",
+                "through2": "2.0.5"
             }
         },
         "mixin-deep": {
@@ -8122,8 +8103,8 @@
             "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
             "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
             "requires": {
-                "for-in": "^1.0.2",
-                "is-extendable": "^1.0.1"
+                "for-in": "1.0.2",
+                "is-extendable": "1.0.1"
             },
             "dependencies": {
                 "is-extendable": {
@@ -8131,14 +8112,14 @@
                     "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
                     "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
                     "requires": {
-                        "is-plain-object": "^2.0.4"
+                        "is-plain-object": "2.0.4"
                     }
                 }
             }
         },
         "mkdirp": {
             "version": "0.5.1",
-            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+            "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
             "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
             "requires": {
                 "minimist": "0.0.8"
@@ -8159,8 +8140,8 @@
             "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-5.4.4.tgz",
             "integrity": "sha512-2mTzpyEjVB/RGk2i6KbcmP4HWcAUFox5ZRCrGvSyz49w20I4C4qql63grPpYrS9E9GKwgydBHQlA4y665LuRCQ==",
             "requires": {
-                "hoist-non-react-statics": "^3.0.0",
-                "react-lifecycles-compat": "^3.0.2"
+                "hoist-non-react-statics": "3.3.0",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "mobx-react-devtools": {
@@ -8219,12 +8200,12 @@
                     "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
                     "dev": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "supports-color": {
@@ -8233,7 +8214,7 @@
                     "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -8243,10 +8224,10 @@
             "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.4.1.tgz",
             "integrity": "sha512-juqt5/Z42J4DcE7tG7UdVaTKmUC6zinF4yioPfpeOSNBieWSK6qCY+0tfGQcHLKrauWPDdMZVROHJOa8q2pWsA==",
             "requires": {
-                "bson": "^1.1.1",
-                "require_optional": "^1.0.1",
-                "safe-buffer": "^5.1.2",
-                "saslprep": "^1.0.0"
+                "bson": "1.1.3",
+                "require_optional": "1.0.1",
+                "safe-buffer": "5.1.2",
+                "saslprep": "1.0.3"
             },
             "dependencies": {
                 "bson": {
@@ -8261,8 +8242,8 @@
             "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz",
             "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==",
             "requires": {
-                "bson": "~1.0.4",
-                "require_optional": "~1.0.0"
+                "bson": "1.0.9",
+                "require_optional": "1.0.1"
             }
         },
         "mongoose": {
@@ -8270,7 +8251,7 @@
             "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.8.4.tgz",
             "integrity": "sha512-jQjLckUILEQUqBuG+ihjtA9OLmrqcIG5n+vaeHpR++TG8/ug5yy5ogkDnybTSq8Ql5OORud3+OCOc2Uw96q32w==",
             "requires": {
-                "bson": "~1.1.1",
+                "bson": "1.1.3",
                 "kareem": "2.3.1",
                 "mongodb": "3.4.1",
                 "mongoose-legacy-pluralize": "1.0.2",
@@ -8306,12 +8287,12 @@
             "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1",
-                "copy-concurrently": "^1.0.0",
-                "fs-write-stream-atomic": "^1.0.8",
-                "mkdirp": "^0.5.1",
-                "rimraf": "^2.5.4",
-                "run-queue": "^1.0.3"
+                "aproba": "1.2.0",
+                "copy-concurrently": "1.0.5",
+                "fs-write-stream-atomic": "1.0.10",
+                "mkdirp": "0.5.1",
+                "rimraf": "2.7.1",
+                "run-queue": "1.0.3"
             },
             "dependencies": {
                 "rimraf": {
@@ -8320,7 +8301,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -8337,7 +8318,7 @@
             "requires": {
                 "bluebird": "3.5.1",
                 "debug": "3.1.0",
-                "regexp-clone": "^1.0.0",
+                "regexp-clone": "1.0.0",
                 "safe-buffer": "5.1.2",
                 "sliced": "1.0.1"
             },
@@ -8368,8 +8349,8 @@
             "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
             "dev": true,
             "requires": {
-                "dns-packet": "^1.3.1",
-                "thunky": "^1.0.2"
+                "dns-packet": "1.3.1",
+                "thunky": "1.1.0"
             }
         },
         "multicast-dns-service-types": {
@@ -8388,17 +8369,17 @@
             "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
             "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
             "requires": {
-                "arr-diff": "^4.0.0",
-                "array-unique": "^0.3.2",
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "fragment-cache": "^0.2.1",
-                "is-windows": "^1.0.2",
-                "kind-of": "^6.0.2",
-                "object.pick": "^1.3.0",
-                "regex-not": "^1.0.0",
-                "snapdragon": "^0.8.1",
-                "to-regex": "^3.0.1"
+                "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.2",
+                "snapdragon": "0.8.2",
+                "to-regex": "3.0.2"
             }
         },
         "napi-build-utils": {
@@ -8416,9 +8397,9 @@
             "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz",
             "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==",
             "requires": {
-                "debug": "^3.2.6",
-                "iconv-lite": "^0.4.4",
-                "sax": "^1.2.4"
+                "debug": "3.2.6",
+                "iconv-lite": "0.4.24",
+                "sax": "1.2.4"
             },
             "dependencies": {
                 "debug": {
@@ -8426,7 +8407,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -8449,7 +8430,7 @@
         },
         "next-tick": {
             "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
             "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
         },
         "nice-try": {
@@ -8463,7 +8444,7 @@
             "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.13.0.tgz",
             "integrity": "sha512-9HrZGFVTR5SOu3PZAnAY2hLO36aW1wmA+FDsVkr85BTST32TLCA1H/AEcatVRAsWLyXS3bqUDYCAjq5/QGuSTA==",
             "requires": {
-                "semver": "^5.4.1"
+                "semver": "5.7.0"
             }
         },
         "node-ensure": {
@@ -8476,8 +8457,8 @@
             "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
             "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==",
             "requires": {
-                "object.getownpropertydescriptors": "^2.0.3",
-                "semver": "^5.7.0"
+                "object.getownpropertydescriptors": "2.0.3",
+                "semver": "5.7.0"
             }
         },
         "node-fetch": {
@@ -8485,8 +8466,8 @@
             "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
             "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
             "requires": {
-                "encoding": "^0.1.11",
-                "is-stream": "^1.0.1"
+                "encoding": "0.1.12",
+                "is-stream": "1.1.0"
             }
         },
         "node-forge": {
@@ -8500,18 +8481,18 @@
             "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
             "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
             "requires": {
-                "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"
+                "fstream": "1.0.12",
+                "glob": "7.1.4",
+                "graceful-fs": "4.2.0",
+                "mkdirp": "0.5.1",
+                "nopt": "3.0.6",
+                "npmlog": "4.1.2",
+                "osenv": "0.1.5",
+                "request": "2.88.0",
+                "rimraf": "2.7.1",
+                "semver": "5.3.0",
+                "tar": "2.2.2",
+                "which": "1.3.1"
             },
             "dependencies": {
                 "nopt": {
@@ -8519,7 +8500,7 @@
                     "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
                     "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
                     "requires": {
-                        "abbrev": "1"
+                        "abbrev": "1.1.1"
                     }
                 },
                 "rimraf": {
@@ -8527,12 +8508,12 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "semver": {
                     "version": "5.3.0",
-                    "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+                    "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
                     "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
                 },
                 "tar": {
@@ -8540,9 +8521,9 @@
                     "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
                     "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
                     "requires": {
-                        "block-stream": "*",
-                        "fstream": "^1.0.12",
-                        "inherits": "2"
+                        "block-stream": "0.0.9",
+                        "fstream": "1.0.12",
+                        "inherits": "2.0.3"
                     }
                 }
             }
@@ -8553,29 +8534,29 @@
             "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
             "dev": true,
             "requires": {
-                "assert": "^1.1.1",
-                "browserify-zlib": "^0.2.0",
-                "buffer": "^4.3.0",
-                "console-browserify": "^1.1.0",
-                "constants-browserify": "^1.0.0",
-                "crypto-browserify": "^3.11.0",
-                "domain-browser": "^1.1.1",
-                "events": "^3.0.0",
-                "https-browserify": "^1.0.0",
-                "os-browserify": "^0.3.0",
+                "assert": "1.5.0",
+                "browserify-zlib": "0.2.0",
+                "buffer": "4.9.2",
+                "console-browserify": "1.2.0",
+                "constants-browserify": "1.0.0",
+                "crypto-browserify": "3.12.0",
+                "domain-browser": "1.2.0",
+                "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",
+                "process": "0.11.10",
+                "punycode": "1.4.1",
+                "querystring-es3": "0.2.1",
+                "readable-stream": "2.3.6",
+                "stream-browserify": "2.0.2",
+                "stream-http": "2.8.3",
+                "string_decoder": "1.1.1",
+                "timers-browserify": "2.0.11",
                 "tty-browserify": "0.0.0",
-                "url": "^0.11.0",
-                "util": "^0.11.0",
-                "vm-browserify": "^1.0.1"
+                "url": "0.11.0",
+                "util": "0.11.1",
+                "vm-browserify": "1.1.2"
             },
             "dependencies": {
                 "buffer": {
@@ -8584,9 +8565,9 @@
                     "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
                     "dev": true,
                     "requires": {
-                        "base64-js": "^1.0.2",
-                        "ieee754": "^1.1.4",
-                        "isarray": "^1.0.0"
+                        "base64-js": "1.3.0",
+                        "ieee754": "1.1.13",
+                        "isarray": "1.0.0"
                     }
                 },
                 "punycode": {
@@ -8603,11 +8584,11 @@
             "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==",
             "dev": true,
             "requires": {
-                "growly": "^1.3.0",
-                "is-wsl": "^1.1.0",
-                "semver": "^5.5.0",
-                "shellwords": "^0.1.1",
-                "which": "^1.3.0"
+                "growly": "1.3.0",
+                "is-wsl": "1.1.0",
+                "semver": "5.7.0",
+                "shellwords": "0.1.1",
+                "which": "1.3.1"
             }
         },
         "node-pre-gyp": {
@@ -8615,16 +8596,16 @@
             "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
             "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
             "requires": {
-                "detect-libc": "^1.0.2",
-                "mkdirp": "^0.5.1",
-                "needle": "^2.2.1",
-                "nopt": "^4.0.1",
-                "npm-packlist": "^1.1.6",
-                "npmlog": "^4.0.2",
-                "rc": "^1.2.7",
-                "rimraf": "^2.6.1",
-                "semver": "^5.3.0",
-                "tar": "^4"
+                "detect-libc": "1.0.3",
+                "mkdirp": "0.5.1",
+                "needle": "2.4.0",
+                "nopt": "4.0.1",
+                "npm-packlist": "1.4.7",
+                "npmlog": "4.1.2",
+                "rc": "1.2.8",
+                "rimraf": "2.7.1",
+                "semver": "5.7.0",
+                "tar": "4.4.10"
             },
             "dependencies": {
                 "rimraf": {
@@ -8632,7 +8613,7 @@
                     "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -8642,23 +8623,23 @@
             "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz",
             "integrity": "sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA==",
             "requires": {
-                "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.4",
-                "stdout-stream": "^1.4.0",
-                "true-case-path": "^1.0.2"
+                "async-foreach": "0.1.3",
+                "chalk": "1.1.3",
+                "cross-spawn": "3.0.1",
+                "gaze": "1.1.3",
+                "get-stdin": "4.0.1",
+                "glob": "7.1.4",
+                "in-publish": "2.0.0",
+                "lodash": "4.17.15",
+                "meow": "3.7.0",
+                "mkdirp": "0.5.1",
+                "nan": "2.14.0",
+                "node-gyp": "3.8.0",
+                "npmlog": "4.1.2",
+                "request": "2.88.0",
+                "sass-graph": "2.2.4",
+                "stdout-stream": "1.4.1",
+                "true-case-path": "1.0.3"
             },
             "dependencies": {
                 "cross-spawn": {
@@ -8666,8 +8647,8 @@
                     "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
                     "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
                     "requires": {
-                        "lru-cache": "^4.0.1",
-                        "which": "^1.2.9"
+                        "lru-cache": "4.1.5",
+                        "which": "1.3.1"
                     }
                 },
                 "get-stdin": {
@@ -8687,16 +8668,16 @@
             "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.4.tgz",
             "integrity": "sha512-VGPaqQBNk193lrJFotBU8nvWZPqEZY2eIzymy2jjY0fJ9qIsxA0sxQ8ATPl0gZC645gijYEc1jtZvpS8QWzJGQ==",
             "requires": {
-                "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"
+                "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"
             },
             "dependencies": {
                 "debug": {
@@ -8704,7 +8685,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -8722,7 +8703,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -8737,8 +8718,8 @@
             "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
             "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
             "requires": {
-                "abbrev": "1",
-                "osenv": "^0.1.4"
+                "abbrev": "1.1.1",
+                "osenv": "0.1.5"
             }
         },
         "normalize-package-data": {
@@ -8746,10 +8727,10 @@
             "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
             "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
             "requires": {
-                "hosted-git-info": "^2.1.4",
-                "resolve": "^1.10.0",
-                "semver": "2 || 3 || 4 || 5",
-                "validate-npm-package-license": "^3.0.1"
+                "hosted-git-info": "2.8.5",
+                "resolve": "1.11.1",
+                "semver": "5.7.0",
+                "validate-npm-package-license": "3.0.4"
             }
         },
         "normalize-path": {
@@ -8767,137 +8748,137 @@
             "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.6.tgz",
             "integrity": "sha512-NomC08kv7HIl1FOyLOe9Hp89kYsOsvx52huVIJ7i8hFW8Xp65lDwe/8wTIrh9q9SaQhA8hTrfXPh3BEL3TmMpw==",
             "requires": {
-                "JSONStream": "^1.3.5",
-                "abbrev": "~1.1.1",
-                "ansicolors": "~0.3.2",
-                "ansistyles": "~0.1.3",
-                "aproba": "^2.0.0",
-                "archy": "~1.0.0",
-                "bin-links": "^1.1.6",
-                "bluebird": "^3.5.5",
-                "byte-size": "^5.0.1",
-                "cacache": "^12.0.3",
-                "call-limit": "^1.1.1",
-                "chownr": "^1.1.3",
-                "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.4",
-                "graceful-fs": "^4.2.3",
-                "has-unicode": "~2.0.1",
-                "hosted-git-info": "^2.8.5",
-                "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",
-                "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.0",
-                "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.1",
-                "move-concurrently": "^1.0.1",
-                "node-gyp": "^5.0.5",
-                "nopt": "~4.0.1",
-                "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.7",
-                "npm-pick-manifest": "^3.0.2",
-                "npm-profile": "^4.0.2",
-                "npm-registry-fetch": "^4.0.2",
-                "npm-user-validate": "~1.0.0",
-                "npmlog": "~4.1.2",
-                "once": "~1.4.0",
-                "opener": "^1.5.1",
-                "osenv": "^0.1.5",
-                "pacote": "^9.5.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.4.0",
-                "readdir-scoped-modules": "^1.1.0",
-                "request": "^2.88.0",
-                "retry": "^0.12.0",
-                "rimraf": "^2.6.3",
-                "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",
+                "JSONStream": "1.3.5",
+                "abbrev": "1.1.1",
+                "ansicolors": "0.3.2",
+                "ansistyles": "0.1.3",
+                "aproba": "2.0.0",
+                "archy": "1.0.0",
+                "bin-links": "1.1.6",
+                "bluebird": "3.5.5",
+                "byte-size": "5.0.1",
+                "cacache": "12.0.3",
+                "call-limit": "1.1.1",
+                "chownr": "1.1.3",
+                "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": "1.0.1",
+                "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.4",
+                "graceful-fs": "4.2.3",
+                "has-unicode": "2.0.1",
+                "hosted-git-info": "2.8.5",
+                "iferr": "1.0.2",
+                "imurmurhash": "0.1.4",
+                "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",
+                "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.0",
+                "lock-verify": "2.1.0",
+                "lockfile": "1.0.4",
+                "lodash._baseindexof": "3.1.0",
+                "lodash._baseuniq": "4.6.0",
+                "lodash._bindcallback": "3.0.1",
+                "lodash._cacheindexof": "3.0.2",
+                "lodash._createcache": "3.1.2",
+                "lodash._getnative": "3.9.1",
+                "lodash.clonedeep": "4.5.0",
+                "lodash.restparam": "3.6.1",
+                "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.1",
+                "move-concurrently": "1.0.1",
+                "node-gyp": "5.0.5",
+                "nopt": "4.0.1",
+                "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.7",
+                "npm-pick-manifest": "3.0.2",
+                "npm-profile": "4.0.2",
+                "npm-registry-fetch": "4.0.2",
+                "npm-user-validate": "1.0.0",
+                "npmlog": "4.1.2",
+                "once": "1.4.0",
+                "opener": "1.5.1",
+                "osenv": "0.1.5",
+                "pacote": "9.5.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.4.0",
+                "readdir-scoped-modules": "1.1.0",
+                "request": "2.88.0",
+                "retry": "0.12.0",
+                "rimraf": "2.6.3",
+                "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"
+                "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"
             },
             "dependencies": {
                 "JSONStream": {
                     "version": "1.3.5",
                     "bundled": true,
                     "requires": {
-                        "jsonparse": "^1.2.0",
-                        "through": ">=2.2.7 <3"
+                        "jsonparse": "1.3.1",
+                        "through": "2.3.8"
                     }
                 },
                 "abbrev": {
@@ -8908,31 +8889,31 @@
                     "version": "4.3.0",
                     "bundled": true,
                     "requires": {
-                        "es6-promisify": "^5.0.0"
+                        "es6-promisify": "5.0.0"
                     }
                 },
                 "agentkeepalive": {
                     "version": "3.5.2",
                     "bundled": true,
                     "requires": {
-                        "humanize-ms": "^1.2.1"
+                        "humanize-ms": "1.2.1"
                     }
                 },
                 "ajv": {
                     "version": "5.5.2",
                     "bundled": true,
                     "requires": {
-                        "co": "^4.6.0",
-                        "fast-deep-equal": "^1.0.0",
-                        "fast-json-stable-stringify": "^2.0.0",
-                        "json-schema-traverse": "^0.3.0"
+                        "co": "4.6.0",
+                        "fast-deep-equal": "1.1.0",
+                        "fast-json-stable-stringify": "2.0.0",
+                        "json-schema-traverse": "0.3.1"
                     }
                 },
                 "ansi-align": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.0.0"
+                        "string-width": "2.1.1"
                     }
                 },
                 "ansi-regex": {
@@ -8943,7 +8924,7 @@
                     "version": "3.2.1",
                     "bundled": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.1"
                     }
                 },
                 "ansicolors": {
@@ -8966,28 +8947,28 @@
                     "version": "1.1.4",
                     "bundled": true,
                     "requires": {
-                        "delegates": "^1.0.0",
-                        "readable-stream": "^2.0.6"
+                        "delegates": "1.0.0",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9000,7 +8981,7 @@
                     "version": "0.2.4",
                     "bundled": true,
                     "requires": {
-                        "safer-buffer": "~2.1.0"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "assert-plus": {
@@ -9028,19 +9009,19 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "tweetnacl": "^0.14.3"
+                        "tweetnacl": "0.14.5"
                     }
                 },
                 "bin-links": {
                     "version": "1.1.6",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "cmd-shim": "3.0.3",
+                        "gentle-fs": "2.3.0",
+                        "graceful-fs": "4.2.3",
+                        "npm-normalize-package-bin": "1.0.1",
+                        "write-file-atomic": "2.4.3"
                     }
                 },
                 "bluebird": {
@@ -9051,20 +9032,20 @@
                     "version": "1.3.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "ansi-align": "2.0.0",
+                        "camelcase": "4.1.0",
+                        "chalk": "2.4.1",
+                        "cli-boxes": "1.0.0",
+                        "string-width": "2.1.1",
+                        "term-size": "1.2.0",
+                        "widest-line": "2.0.0"
                     }
                 },
                 "brace-expansion": {
                     "version": "1.1.11",
                     "bundled": true,
                     "requires": {
-                        "balanced-match": "^1.0.0",
+                        "balanced-match": "1.0.0",
                         "concat-map": "0.0.1"
                     }
                 },
@@ -9088,21 +9069,21 @@
                     "version": "12.0.3",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "chownr": "1.1.3",
+                        "figgy-pudding": "3.5.1",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "infer-owner": "1.0.4",
+                        "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"
                     }
                 },
                 "call-limit": {
@@ -9125,9 +9106,9 @@
                     "version": "2.4.1",
                     "bundled": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.4.0"
                     }
                 },
                 "chownr": {
@@ -9142,7 +9123,7 @@
                     "version": "2.0.10",
                     "bundled": true,
                     "requires": {
-                        "ip-regex": "^2.1.0"
+                        "ip-regex": "2.1.0"
                     }
                 },
                 "cli-boxes": {
@@ -9153,26 +9134,26 @@
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.0.0",
-                        "strip-ansi": "^3.0.1"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "3.0.1"
                     }
                 },
                 "cli-table3": {
                     "version": "0.5.1",
                     "bundled": true,
                     "requires": {
-                        "colors": "^1.1.2",
-                        "object-assign": "^4.1.0",
-                        "string-width": "^2.1.1"
+                        "colors": "1.3.3",
+                        "object-assign": "4.1.1",
+                        "string-width": "2.1.1"
                     }
                 },
                 "cliui": {
                     "version": "4.1.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.1.1",
-                        "strip-ansi": "^4.0.0",
-                        "wrap-ansi": "^2.0.0"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "4.0.0",
+                        "wrap-ansi": "2.1.0"
                     },
                     "dependencies": {
                         "ansi-regex": {
@@ -9183,7 +9164,7 @@
                             "version": "4.0.0",
                             "bundled": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -9196,8 +9177,8 @@
                     "version": "3.0.3",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "mkdirp": "~0.5.0"
+                        "graceful-fs": "4.2.3",
+                        "mkdirp": "0.5.1"
                     }
                 },
                 "co": {
@@ -9212,7 +9193,7 @@
                     "version": "1.9.1",
                     "bundled": true,
                     "requires": {
-                        "color-name": "^1.1.1"
+                        "color-name": "1.1.3"
                     }
                 },
                 "color-name": {
@@ -9228,15 +9209,15 @@
                     "version": "1.5.4",
                     "bundled": true,
                     "requires": {
-                        "strip-ansi": "^3.0.0",
-                        "wcwidth": "^1.0.0"
+                        "strip-ansi": "3.0.1",
+                        "wcwidth": "1.0.1"
                     }
                 },
                 "combined-stream": {
                     "version": "1.0.6",
                     "bundled": true,
                     "requires": {
-                        "delayed-stream": "~1.0.0"
+                        "delayed-stream": "1.0.0"
                     }
                 },
                 "concat-map": {
@@ -9247,30 +9228,30 @@
                     "version": "1.6.2",
                     "bundled": true,
                     "requires": {
-                        "buffer-from": "^1.0.0",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^2.2.2",
-                        "typedarray": "^0.0.6"
+                        "buffer-from": "1.0.0",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6",
+                        "typedarray": "0.0.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9279,20 +9260,20 @@
                     "version": "1.1.12",
                     "bundled": true,
                     "requires": {
-                        "ini": "^1.3.4",
-                        "proto-list": "~1.2.1"
+                        "ini": "1.3.5",
+                        "proto-list": "1.2.4"
                     }
                 },
                 "configstore": {
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "dot-prop": "4.2.0",
+                        "graceful-fs": "4.2.3",
+                        "make-dir": "1.3.0",
+                        "unique-string": "1.0.0",
+                        "write-file-atomic": "2.4.3",
+                        "xdg-basedir": "3.0.0"
                     }
                 },
                 "console-control-strings": {
@@ -9303,12 +9284,12 @@
                     "version": "1.0.5",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1",
-                        "fs-write-stream-atomic": "^1.0.8",
-                        "iferr": "^0.1.5",
-                        "mkdirp": "^0.5.1",
-                        "rimraf": "^2.5.4",
-                        "run-queue": "^1.0.0"
+                        "aproba": "1.2.0",
+                        "fs-write-stream-atomic": "1.0.10",
+                        "iferr": "0.1.5",
+                        "mkdirp": "0.5.1",
+                        "rimraf": "2.6.3",
+                        "run-queue": "1.0.3"
                     },
                     "dependencies": {
                         "aproba": {
@@ -9329,24 +9310,24 @@
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "capture-stack-trace": "^1.0.0"
+                        "capture-stack-trace": "1.0.0"
                     }
                 },
                 "cross-spawn": {
                     "version": "5.1.0",
                     "bundled": true,
                     "requires": {
-                        "lru-cache": "^4.0.1",
-                        "shebang-command": "^1.2.0",
-                        "which": "^1.2.9"
+                        "lru-cache": "4.1.5",
+                        "shebang-command": "1.2.0",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "lru-cache": {
                             "version": "4.1.5",
                             "bundled": true,
                             "requires": {
-                                "pseudomap": "^1.0.2",
-                                "yallist": "^2.1.2"
+                                "pseudomap": "1.0.2",
+                                "yallist": "2.1.2"
                             }
                         },
                         "yallist": {
@@ -9367,7 +9348,7 @@
                     "version": "1.14.1",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0"
+                        "assert-plus": "1.0.0"
                     }
                 },
                 "debug": {
@@ -9403,14 +9384,14 @@
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "clone": "^1.0.2"
+                        "clone": "1.0.4"
                     }
                 },
                 "define-properties": {
                     "version": "1.1.3",
                     "bundled": true,
                     "requires": {
-                        "object-keys": "^1.0.12"
+                        "object-keys": "1.0.12"
                     }
                 },
                 "delayed-stream": {
@@ -9433,15 +9414,15 @@
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "asap": "^2.0.0",
-                        "wrappy": "1"
+                        "asap": "2.0.6",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "dot-prop": {
                     "version": "4.2.0",
                     "bundled": true,
                     "requires": {
-                        "is-obj": "^1.0.0"
+                        "is-obj": "1.0.1"
                     }
                 },
                 "dotenv": {
@@ -9456,30 +9437,30 @@
                     "version": "3.6.0",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.0.0",
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.0",
-                        "stream-shift": "^1.0.0"
+                        "end-of-stream": "1.4.1",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6",
+                        "stream-shift": "1.0.0"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9489,8 +9470,8 @@
                     "bundled": true,
                     "optional": true,
                     "requires": {
-                        "jsbn": "~0.1.0",
-                        "safer-buffer": "^2.1.0"
+                        "jsbn": "0.1.1",
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "editor": {
@@ -9501,14 +9482,14 @@
                     "version": "0.1.12",
                     "bundled": true,
                     "requires": {
-                        "iconv-lite": "~0.4.13"
+                        "iconv-lite": "0.4.23"
                     }
                 },
                 "end-of-stream": {
                     "version": "1.4.1",
                     "bundled": true,
                     "requires": {
-                        "once": "^1.4.0"
+                        "once": "1.4.0"
                     }
                 },
                 "env-paths": {
@@ -9523,27 +9504,27 @@
                     "version": "0.1.7",
                     "bundled": true,
                     "requires": {
-                        "prr": "~1.0.1"
+                        "prr": "1.0.1"
                     }
                 },
                 "es-abstract": {
                     "version": "1.12.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "es-to-primitive": "1.2.0",
+                        "function-bind": "1.1.1",
+                        "has": "1.0.3",
+                        "is-callable": "1.1.4",
+                        "is-regex": "1.0.4"
                     }
                 },
                 "es-to-primitive": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "is-callable": "^1.1.4",
-                        "is-date-object": "^1.0.1",
-                        "is-symbol": "^1.0.2"
+                        "is-callable": "1.1.4",
+                        "is-date-object": "1.0.1",
+                        "is-symbol": "1.0.2"
                     }
                 },
                 "es6-promise": {
@@ -9554,7 +9535,7 @@
                     "version": "5.0.0",
                     "bundled": true,
                     "requires": {
-                        "es6-promise": "^4.0.3"
+                        "es6-promise": "4.2.8"
                     }
                 },
                 "escape-string-regexp": {
@@ -9565,13 +9546,13 @@
                     "version": "0.7.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "cross-spawn": "5.1.0",
+                        "get-stream": "3.0.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     },
                     "dependencies": {
                         "get-stream": {
@@ -9608,35 +9589,35 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "locate-path": "^2.0.0"
+                        "locate-path": "2.0.0"
                     }
                 },
                 "flush-write-stream": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.4"
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9649,37 +9630,37 @@
                     "version": "2.3.2",
                     "bundled": true,
                     "requires": {
-                        "asynckit": "^0.4.0",
+                        "asynckit": "0.4.0",
                         "combined-stream": "1.0.6",
-                        "mime-types": "^2.1.12"
+                        "mime-types": "2.1.19"
                     }
                 },
                 "from2": {
                     "version": "2.3.0",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.1",
-                        "readable-stream": "^2.0.0"
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9688,15 +9669,15 @@
                     "version": "1.2.7",
                     "bundled": true,
                     "requires": {
-                        "minipass": "^2.6.0"
+                        "minipass": "2.9.0"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -9705,19 +9686,19 @@
                     "version": "1.2.10",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "path-is-inside": "^1.0.1",
-                        "rimraf": "^2.5.2"
+                        "graceful-fs": "4.2.3",
+                        "path-is-inside": "1.0.2",
+                        "rimraf": "2.6.3"
                     }
                 },
                 "fs-write-stream-atomic": {
                     "version": "1.0.10",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2",
-                        "iferr": "^0.1.5",
-                        "imurmurhash": "^0.1.4",
-                        "readable-stream": "1 || 2"
+                        "graceful-fs": "4.2.3",
+                        "iferr": "0.1.5",
+                        "imurmurhash": "0.1.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "iferr": {
@@ -9728,20 +9709,20 @@
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -9758,14 +9739,14 @@
                     "version": "2.7.4",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.0.3",
-                        "console-control-strings": "^1.0.0",
-                        "has-unicode": "^2.0.0",
-                        "object-assign": "^4.1.0",
-                        "signal-exit": "^3.0.0",
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1",
-                        "wide-align": "^1.1.0"
+                        "aproba": "1.2.0",
+                        "console-control-strings": "1.1.0",
+                        "has-unicode": "2.0.1",
+                        "object-assign": "4.1.1",
+                        "signal-exit": "3.0.2",
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1",
+                        "wide-align": "1.1.2"
                     },
                     "dependencies": {
                         "aproba": {
@@ -9776,9 +9757,9 @@
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -9791,17 +9772,17 @@
                     "version": "2.3.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "aproba": "1.2.0",
+                        "chownr": "1.1.3",
+                        "cmd-shim": "3.0.3",
+                        "fs-vacuum": "1.2.10",
+                        "graceful-fs": "4.2.3",
+                        "iferr": "0.1.5",
+                        "infer-owner": "1.0.4",
+                        "mkdirp": "0.5.1",
+                        "path-is-inside": "1.0.2",
+                        "read-cmd-shim": "1.0.5",
+                        "slide": "1.1.6"
                     },
                     "dependencies": {
                         "aproba": {
@@ -9822,50 +9803,50 @@
                     "version": "4.1.0",
                     "bundled": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "getpass": {
                     "version": "0.1.7",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0"
+                        "assert-plus": "1.0.0"
                     }
                 },
                 "glob": {
                     "version": "7.1.4",
                     "bundled": true,
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.4",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "global-dirs": {
                     "version": "0.1.1",
                     "bundled": true,
                     "requires": {
-                        "ini": "^1.3.4"
+                        "ini": "1.3.5"
                     }
                 },
                 "got": {
                     "version": "6.7.1",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "create-error-class": "3.0.2",
+                        "duplexer3": "0.1.4",
+                        "get-stream": "3.0.0",
+                        "is-redirect": "1.0.0",
+                        "is-retry-allowed": "1.1.0",
+                        "is-stream": "1.1.0",
+                        "lowercase-keys": "1.0.1",
+                        "safe-buffer": "5.1.2",
+                        "timed-out": "4.0.1",
+                        "unzip-response": "2.0.1",
+                        "url-parse-lax": "1.0.0"
                     },
                     "dependencies": {
                         "get-stream": {
@@ -9886,15 +9867,15 @@
                     "version": "5.1.0",
                     "bundled": true,
                     "requires": {
-                        "ajv": "^5.3.0",
-                        "har-schema": "^2.0.0"
+                        "ajv": "5.5.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "has": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "function-bind": "^1.1.1"
+                        "function-bind": "1.1.1"
                     }
                 },
                 "has-flag": {
@@ -9921,7 +9902,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "4",
+                        "agent-base": "4.3.0",
                         "debug": "3.1.0"
                     }
                 },
@@ -9929,31 +9910,31 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.14.2"
                     }
                 },
                 "https-proxy-agent": {
                     "version": "2.2.4",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "^4.3.0",
-                        "debug": "^3.1.0"
+                        "agent-base": "4.3.0",
+                        "debug": "3.1.0"
                     }
                 },
                 "humanize-ms": {
                     "version": "1.2.1",
                     "bundled": true,
                     "requires": {
-                        "ms": "^2.0.0"
+                        "ms": "2.1.1"
                     }
                 },
                 "iconv-lite": {
                     "version": "0.4.23",
                     "bundled": true,
                     "requires": {
-                        "safer-buffer": ">= 2.1.2 < 3"
+                        "safer-buffer": "2.1.2"
                     }
                 },
                 "iferr": {
@@ -9964,7 +9945,7 @@
                     "version": "3.0.3",
                     "bundled": true,
                     "requires": {
-                        "minimatch": "^3.0.4"
+                        "minimatch": "3.0.4"
                     }
                 },
                 "import-lazy": {
@@ -9983,8 +9964,8 @@
                     "version": "1.0.6",
                     "bundled": true,
                     "requires": {
-                        "once": "^1.3.0",
-                        "wrappy": "1"
+                        "once": "1.4.0",
+                        "wrappy": "1.0.2"
                     }
                 },
                 "inherits": {
@@ -9999,14 +9980,14 @@
                     "version": "1.10.3",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "glob": "7.1.4",
+                        "npm-package-arg": "6.1.1",
+                        "promzard": "0.3.0",
+                        "read": "1.0.7",
+                        "read-package-json": "2.1.1",
+                        "semver": "5.7.1",
+                        "validate-npm-package-license": "3.0.4",
+                        "validate-npm-package-name": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -10029,7 +10010,7 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "ci-info": "^1.0.0"
+                        "ci-info": "1.6.0"
                     },
                     "dependencies": {
                         "ci-info": {
@@ -10042,7 +10023,7 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "cidr-regex": "^2.0.10"
+                        "cidr-regex": "2.0.10"
                     }
                 },
                 "is-date-object": {
@@ -10053,15 +10034,15 @@
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "number-is-nan": "^1.0.0"
+                        "number-is-nan": "1.0.1"
                     }
                 },
                 "is-installed-globally": {
                     "version": "0.1.0",
                     "bundled": true,
                     "requires": {
-                        "global-dirs": "^0.1.0",
-                        "is-path-inside": "^1.0.0"
+                        "global-dirs": "0.1.1",
+                        "is-path-inside": "1.0.1"
                     }
                 },
                 "is-npm": {
@@ -10076,7 +10057,7 @@
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "path-is-inside": "^1.0.1"
+                        "path-is-inside": "1.0.2"
                     }
                 },
                 "is-redirect": {
@@ -10087,7 +10068,7 @@
                     "version": "1.0.4",
                     "bundled": true,
                     "requires": {
-                        "has": "^1.0.1"
+                        "has": "1.0.3"
                     }
                 },
                 "is-retry-allowed": {
@@ -10102,7 +10083,7 @@
                     "version": "1.0.2",
                     "bundled": true,
                     "requires": {
-                        "has-symbols": "^1.0.0"
+                        "has-symbols": "1.0.0"
                     }
                 },
                 "is-typedarray": {
@@ -10160,7 +10141,7 @@
                     "version": "3.1.0",
                     "bundled": true,
                     "requires": {
-                        "package-json": "^4.0.0"
+                        "package-json": "4.0.1"
                     }
                 },
                 "lazy-property": {
@@ -10171,102 +10152,102 @@
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "invert-kv": "^1.0.0"
+                        "invert-kv": "1.0.0"
                     }
                 },
                 "libcipm": {
                     "version": "4.0.7",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bin-links": "1.1.6",
+                        "bluebird": "3.5.5",
+                        "figgy-pudding": "3.5.1",
+                        "find-npm-prefix": "1.0.2",
+                        "graceful-fs": "4.2.3",
+                        "ini": "1.3.5",
+                        "lock-verify": "2.1.0",
+                        "mkdirp": "0.5.1",
+                        "npm-lifecycle": "3.1.4",
+                        "npm-logical-tree": "1.2.1",
+                        "npm-package-arg": "6.1.1",
+                        "pacote": "9.5.12",
+                        "read-package-json": "2.1.1",
+                        "rimraf": "2.6.3",
+                        "worker-farm": "1.7.0"
                     }
                 },
                 "libnpm": {
                     "version": "3.0.1",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bin-links": "1.1.6",
+                        "bluebird": "3.5.5",
+                        "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.1.0",
+                        "npm-lifecycle": "3.1.4",
+                        "npm-logical-tree": "1.2.1",
+                        "npm-package-arg": "6.1.1",
+                        "npm-profile": "4.0.2",
+                        "npm-registry-fetch": "4.0.2",
+                        "npmlog": "4.1.2",
+                        "pacote": "9.5.12",
+                        "read-package-json": "2.1.1",
+                        "stringify-package": "1.0.1"
                     }
                 },
                 "libnpmaccess": {
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "get-stream": "^4.0.0",
-                        "npm-package-arg": "^6.1.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "get-stream": "4.1.0",
+                        "npm-package-arg": "6.1.1",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmconfig": {
                     "version": "1.2.1",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "find-up": "^3.0.0",
-                        "ini": "^1.3.5"
+                        "figgy-pudding": "3.5.1",
+                        "find-up": "3.0.0",
+                        "ini": "1.3.5"
                     },
                     "dependencies": {
                         "find-up": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "locate-path": "^3.0.0"
+                                "locate-path": "3.0.0"
                             }
                         },
                         "locate-path": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "p-locate": "^3.0.0",
-                                "path-exists": "^3.0.0"
+                                "p-locate": "3.0.0",
+                                "path-exists": "3.0.0"
                             }
                         },
                         "p-limit": {
                             "version": "2.2.0",
                             "bundled": true,
                             "requires": {
-                                "p-try": "^2.0.0"
+                                "p-try": "2.2.0"
                             }
                         },
                         "p-locate": {
                             "version": "3.0.0",
                             "bundled": true,
                             "requires": {
-                                "p-limit": "^2.0.0"
+                                "p-limit": "2.2.0"
                             }
                         },
                         "p-try": {
@@ -10279,91 +10260,91 @@
                     "version": "5.0.3",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmorg": {
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmpublish": {
                     "version": "1.1.2",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "lodash.clonedeep": "4.5.0",
+                        "normalize-package-data": "2.5.0",
+                        "npm-package-arg": "6.1.1",
+                        "npm-registry-fetch": "4.0.2",
+                        "semver": "5.7.1",
+                        "ssri": "6.0.1"
                     }
                 },
                 "libnpmsearch": {
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpmteam": {
                     "version": "1.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^2.0.0",
-                        "figgy-pudding": "^3.4.1",
-                        "get-stream": "^4.0.0",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "libnpx": {
                     "version": "10.2.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "dotenv": "5.0.1",
+                        "npm-package-arg": "6.1.1",
+                        "rimraf": "2.6.3",
+                        "safe-buffer": "5.1.2",
+                        "update-notifier": "2.5.0",
+                        "which": "1.3.1",
+                        "y18n": "4.0.0",
+                        "yargs": "11.0.0"
                     }
                 },
                 "locate-path": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "p-locate": "^2.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "2.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "lock-verify": {
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "npm-package-arg": "^6.1.0",
-                        "semver": "^5.4.1"
+                        "npm-package-arg": "6.1.1",
+                        "semver": "5.7.1"
                     }
                 },
                 "lockfile": {
                     "version": "1.0.4",
                     "bundled": true,
                     "requires": {
-                        "signal-exit": "^3.0.2"
+                        "signal-exit": "3.0.2"
                     }
                 },
                 "lodash._baseindexof": {
@@ -10374,8 +10355,8 @@
                     "version": "4.6.0",
                     "bundled": true,
                     "requires": {
-                        "lodash._createset": "~4.0.0",
-                        "lodash._root": "~3.0.0"
+                        "lodash._createset": "4.0.3",
+                        "lodash._root": "3.0.1"
                     }
                 },
                 "lodash._bindcallback": {
@@ -10390,7 +10371,7 @@
                     "version": "3.1.2",
                     "bundled": true,
                     "requires": {
-                        "lodash._getnative": "^3.0.0"
+                        "lodash._getnative": "3.9.1"
                     }
                 },
                 "lodash._createset": {
@@ -10433,31 +10414,31 @@
                     "version": "5.1.1",
                     "bundled": true,
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 },
                 "make-dir": {
                     "version": "1.3.0",
                     "bundled": true,
                     "requires": {
-                        "pify": "^3.0.0"
+                        "pify": "3.0.0"
                     }
                 },
                 "make-fetch-happen": {
                     "version": "5.0.2",
                     "bundled": true,
                     "requires": {
-                        "agentkeepalive": "^3.4.1",
-                        "cacache": "^12.0.0",
-                        "http-cache-semantics": "^3.8.1",
-                        "http-proxy-agent": "^2.1.0",
-                        "https-proxy-agent": "^2.2.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"
+                        "agentkeepalive": "3.5.2",
+                        "cacache": "12.0.3",
+                        "http-cache-semantics": "3.8.1",
+                        "http-proxy-agent": "2.1.0",
+                        "https-proxy-agent": "2.2.4",
+                        "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.2",
+                        "ssri": "6.0.1"
                     }
                 },
                 "meant": {
@@ -10468,7 +10449,7 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "mimic-fn": "^1.0.0"
+                        "mimic-fn": "1.2.0"
                     }
                 },
                 "mime-db": {
@@ -10479,7 +10460,7 @@
                     "version": "2.1.19",
                     "bundled": true,
                     "requires": {
-                        "mime-db": "~1.35.0"
+                        "mime-db": "1.35.0"
                     }
                 },
                 "mimic-fn": {
@@ -10490,7 +10471,7 @@
                     "version": "3.0.4",
                     "bundled": true,
                     "requires": {
-                        "brace-expansion": "^1.1.7"
+                        "brace-expansion": "1.1.11"
                     }
                 },
                 "minimist": {
@@ -10501,15 +10482,15 @@
                     "version": "1.3.3",
                     "bundled": true,
                     "requires": {
-                        "minipass": "^2.9.0"
+                        "minipass": "2.9.0"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -10518,16 +10499,16 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "concat-stream": "^1.5.0",
-                        "duplexify": "^3.4.2",
-                        "end-of-stream": "^1.1.0",
-                        "flush-write-stream": "^1.0.0",
-                        "from2": "^2.1.0",
-                        "parallel-transform": "^1.1.0",
-                        "pump": "^3.0.0",
-                        "pumpify": "^1.3.3",
-                        "stream-each": "^1.1.0",
-                        "through2": "^2.0.0"
+                        "concat-stream": "1.6.2",
+                        "duplexify": "3.6.0",
+                        "end-of-stream": "1.4.1",
+                        "flush-write-stream": "1.0.3",
+                        "from2": "2.3.0",
+                        "parallel-transform": "1.1.0",
+                        "pump": "3.0.0",
+                        "pumpify": "1.5.1",
+                        "stream-each": "1.2.2",
+                        "through2": "2.0.3"
                     }
                 },
                 "mkdirp": {
@@ -10541,12 +10522,12 @@
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1",
-                        "copy-concurrently": "^1.0.0",
-                        "fs-write-stream-atomic": "^1.0.8",
-                        "mkdirp": "^0.5.1",
-                        "rimraf": "^2.5.4",
-                        "run-queue": "^1.0.3"
+                        "aproba": "1.2.0",
+                        "copy-concurrently": "1.0.5",
+                        "fs-write-stream-atomic": "1.0.10",
+                        "mkdirp": "0.5.1",
+                        "rimraf": "2.6.3",
+                        "run-queue": "1.0.3"
                     },
                     "dependencies": {
                         "aproba": {
@@ -10567,33 +10548,33 @@
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "encoding": "^0.1.11",
-                        "json-parse-better-errors": "^1.0.0",
-                        "safe-buffer": "^5.1.1"
+                        "encoding": "0.1.12",
+                        "json-parse-better-errors": "1.0.2",
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "node-gyp": {
                     "version": "5.0.5",
                     "bundled": true,
                     "requires": {
-                        "env-paths": "^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",
-                        "request": "^2.87.0",
-                        "rimraf": "2",
-                        "semver": "~5.3.0",
-                        "tar": "^4.4.12",
-                        "which": "1"
+                        "env-paths": "1.0.0",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "mkdirp": "0.5.1",
+                        "nopt": "3.0.6",
+                        "npmlog": "4.1.2",
+                        "request": "2.88.0",
+                        "rimraf": "2.6.3",
+                        "semver": "5.3.0",
+                        "tar": "4.4.13",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "nopt": {
                             "version": "3.0.6",
                             "bundled": true,
                             "requires": {
-                                "abbrev": "1"
+                                "abbrev": "1.1.1"
                             }
                         },
                         "semver": {
@@ -10606,25 +10587,25 @@
                     "version": "4.0.1",
                     "bundled": true,
                     "requires": {
-                        "abbrev": "1",
-                        "osenv": "^0.1.4"
+                        "abbrev": "1.1.1",
+                        "osenv": "0.1.5"
                     }
                 },
                 "normalize-package-data": {
                     "version": "2.5.0",
                     "bundled": true,
                     "requires": {
-                        "hosted-git-info": "^2.1.4",
-                        "resolve": "^1.10.0",
-                        "semver": "2 || 3 || 4 || 5",
-                        "validate-npm-package-license": "^3.0.1"
+                        "hosted-git-info": "2.8.5",
+                        "resolve": "1.10.0",
+                        "semver": "5.7.1",
+                        "validate-npm-package-license": "3.0.4"
                     },
                     "dependencies": {
                         "resolve": {
                             "version": "1.10.0",
                             "bundled": true,
                             "requires": {
-                                "path-parse": "^1.0.6"
+                                "path-parse": "1.0.6"
                             }
                         }
                     }
@@ -10633,15 +10614,15 @@
                     "version": "1.3.2",
                     "bundled": true,
                     "requires": {
-                        "cli-table3": "^0.5.0",
-                        "console-control-strings": "^1.1.0"
+                        "cli-table3": "0.5.1",
+                        "console-control-strings": "1.1.0"
                     }
                 },
                 "npm-bundled": {
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "npm-normalize-package-bin": "^1.0.1"
+                        "npm-normalize-package-bin": "1.0.1"
                     }
                 },
                 "npm-cache-filename": {
@@ -10652,21 +10633,21 @@
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "semver": "^2.3.0 || 3.x || 4 || 5"
+                        "semver": "5.7.1"
                     }
                 },
                 "npm-lifecycle": {
                     "version": "3.1.4",
                     "bundled": true,
                     "requires": {
-                        "byline": "^5.0.0",
-                        "graceful-fs": "^4.1.15",
-                        "node-gyp": "^5.0.2",
-                        "resolve-from": "^4.0.0",
-                        "slide": "^1.1.6",
+                        "byline": "5.0.0",
+                        "graceful-fs": "4.2.3",
+                        "node-gyp": "5.0.5",
+                        "resolve-from": "4.0.0",
+                        "slide": "1.1.6",
                         "uid-number": "0.0.6",
-                        "umask": "^1.1.0",
-                        "which": "^1.3.1"
+                        "umask": "1.1.0",
+                        "which": "1.3.1"
                     }
                 },
                 "npm-logical-tree": {
@@ -10681,49 +10662,49 @@
                     "version": "6.1.1",
                     "bundled": true,
                     "requires": {
-                        "hosted-git-info": "^2.7.1",
-                        "osenv": "^0.1.5",
-                        "semver": "^5.6.0",
-                        "validate-npm-package-name": "^3.0.0"
+                        "hosted-git-info": "2.8.5",
+                        "osenv": "0.1.5",
+                        "semver": "5.7.1",
+                        "validate-npm-package-name": "3.0.0"
                     }
                 },
                 "npm-packlist": {
                     "version": "1.4.7",
                     "bundled": true,
                     "requires": {
-                        "ignore-walk": "^3.0.1",
-                        "npm-bundled": "^1.0.1"
+                        "ignore-walk": "3.0.3",
+                        "npm-bundled": "1.1.1"
                     }
                 },
                 "npm-pick-manifest": {
                     "version": "3.0.2",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1",
-                        "npm-package-arg": "^6.0.0",
-                        "semver": "^5.4.1"
+                        "figgy-pudding": "3.5.1",
+                        "npm-package-arg": "6.1.1",
+                        "semver": "5.7.1"
                     }
                 },
                 "npm-profile": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.2 || 2",
-                        "figgy-pudding": "^3.4.1",
-                        "npm-registry-fetch": "^4.0.0"
+                        "aproba": "2.0.0",
+                        "figgy-pudding": "3.5.1",
+                        "npm-registry-fetch": "4.0.2"
                     }
                 },
                 "npm-registry-fetch": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "JSONStream": "^1.3.4",
-                        "bluebird": "^3.5.1",
-                        "figgy-pudding": "^3.4.1",
-                        "lru-cache": "^5.1.1",
-                        "make-fetch-happen": "^5.0.0",
-                        "npm-package-arg": "^6.1.0",
-                        "safe-buffer": "^5.2.0"
+                        "JSONStream": "1.3.5",
+                        "bluebird": "3.5.5",
+                        "figgy-pudding": "3.5.1",
+                        "lru-cache": "5.1.1",
+                        "make-fetch-happen": "5.0.2",
+                        "npm-package-arg": "6.1.1",
+                        "safe-buffer": "5.2.0"
                     },
                     "dependencies": {
                         "safe-buffer": {
@@ -10736,7 +10717,7 @@
                     "version": "2.0.2",
                     "bundled": true,
                     "requires": {
-                        "path-key": "^2.0.0"
+                        "path-key": "2.0.1"
                     }
                 },
                 "npm-user-validate": {
@@ -10747,10 +10728,10 @@
                     "version": "4.1.2",
                     "bundled": true,
                     "requires": {
-                        "are-we-there-yet": "~1.1.2",
-                        "console-control-strings": "~1.1.0",
-                        "gauge": "~2.7.3",
-                        "set-blocking": "~2.0.0"
+                        "are-we-there-yet": "1.1.4",
+                        "console-control-strings": "1.1.0",
+                        "gauge": "2.7.4",
+                        "set-blocking": "2.0.0"
                     }
                 },
                 "number-is-nan": {
@@ -10773,15 +10754,15 @@
                     "version": "2.0.3",
                     "bundled": true,
                     "requires": {
-                        "define-properties": "^1.1.2",
-                        "es-abstract": "^1.5.1"
+                        "define-properties": "1.1.3",
+                        "es-abstract": "1.12.0"
                     }
                 },
                 "once": {
                     "version": "1.4.0",
                     "bundled": true,
                     "requires": {
-                        "wrappy": "1"
+                        "wrappy": "1.0.2"
                     }
                 },
                 "opener": {
@@ -10796,9 +10777,9 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "execa": "^0.7.0",
-                        "lcid": "^1.0.0",
-                        "mem": "^1.1.0"
+                        "execa": "0.7.0",
+                        "lcid": "1.0.0",
+                        "mem": "1.1.0"
                     }
                 },
                 "os-tmpdir": {
@@ -10809,8 +10790,8 @@
                     "version": "0.1.5",
                     "bundled": true,
                     "requires": {
-                        "os-homedir": "^1.0.0",
-                        "os-tmpdir": "^1.0.0"
+                        "os-homedir": "1.0.2",
+                        "os-tmpdir": "1.0.2"
                     }
                 },
                 "p-finally": {
@@ -10821,14 +10802,14 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 },
                 "p-locate": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "p-limit": "^1.1.0"
+                        "p-limit": "1.2.0"
                     }
                 },
                 "p-try": {
@@ -10839,54 +10820,54 @@
                     "version": "4.0.1",
                     "bundled": true,
                     "requires": {
-                        "got": "^6.7.1",
-                        "registry-auth-token": "^3.0.1",
-                        "registry-url": "^3.0.3",
-                        "semver": "^5.1.0"
+                        "got": "6.7.1",
+                        "registry-auth-token": "3.3.2",
+                        "registry-url": "3.1.0",
+                        "semver": "5.7.1"
                     }
                 },
                 "pacote": {
                     "version": "9.5.12",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.5.5",
+                        "cacache": "12.0.3",
+                        "chownr": "1.1.3",
+                        "figgy-pudding": "3.5.1",
+                        "get-stream": "4.1.0",
+                        "glob": "7.1.4",
+                        "infer-owner": "1.0.4",
+                        "lru-cache": "5.1.1",
+                        "make-fetch-happen": "5.0.2",
+                        "minimatch": "3.0.4",
+                        "minipass": "2.9.0",
+                        "mississippi": "3.0.0",
+                        "mkdirp": "0.5.1",
+                        "normalize-package-data": "2.5.0",
+                        "npm-normalize-package-bin": "1.0.1",
+                        "npm-package-arg": "6.1.1",
+                        "npm-packlist": "1.4.7",
+                        "npm-pick-manifest": "3.0.2",
+                        "npm-registry-fetch": "4.0.2",
+                        "osenv": "0.1.5",
+                        "promise-inflight": "1.0.1",
+                        "promise-retry": "1.1.1",
+                        "protoduck": "5.0.1",
+                        "rimraf": "2.6.3",
+                        "safe-buffer": "5.1.2",
+                        "semver": "5.7.1",
+                        "ssri": "6.0.1",
+                        "tar": "4.4.13",
+                        "unique-filename": "1.1.1",
+                        "which": "1.3.1"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -10895,29 +10876,29 @@
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "cyclist": "~0.2.2",
-                        "inherits": "^2.0.3",
-                        "readable-stream": "^2.1.5"
+                        "cyclist": "0.2.2",
+                        "inherits": "2.0.4",
+                        "readable-stream": "2.3.6"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -10966,8 +10947,8 @@
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "err-code": "^1.0.0",
-                        "retry": "^0.10.0"
+                        "err-code": "1.1.2",
+                        "retry": "0.10.1"
                     },
                     "dependencies": {
                         "retry": {
@@ -10980,7 +10961,7 @@
                     "version": "0.3.0",
                     "bundled": true,
                     "requires": {
-                        "read": "1"
+                        "read": "1.0.7"
                     }
                 },
                 "proto-list": {
@@ -10991,7 +10972,7 @@
                     "version": "5.0.1",
                     "bundled": true,
                     "requires": {
-                        "genfun": "^5.0.0"
+                        "genfun": "5.0.0"
                     }
                 },
                 "prr": {
@@ -11010,25 +10991,25 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "pumpify": {
                     "version": "1.5.1",
                     "bundled": true,
                     "requires": {
-                        "duplexify": "^3.6.0",
-                        "inherits": "^2.0.3",
-                        "pump": "^2.0.0"
+                        "duplexify": "3.6.0",
+                        "inherits": "2.0.4",
+                        "pump": "2.0.1"
                     },
                     "dependencies": {
                         "pump": {
                             "version": "2.0.1",
                             "bundled": true,
                             "requires": {
-                                "end-of-stream": "^1.1.0",
-                                "once": "^1.3.1"
+                                "end-of-stream": "1.4.1",
+                                "once": "1.4.0"
                             }
                         }
                     }
@@ -11049,9 +11030,9 @@
                     "version": "6.8.2",
                     "bundled": true,
                     "requires": {
-                        "decode-uri-component": "^0.2.0",
-                        "split-on-first": "^1.0.0",
-                        "strict-uri-encode": "^2.0.0"
+                        "decode-uri-component": "0.2.0",
+                        "split-on-first": "1.1.0",
+                        "strict-uri-encode": "2.0.0"
                     }
                 },
                 "qw": {
@@ -11062,10 +11043,10 @@
                     "version": "1.2.7",
                     "bundled": true,
                     "requires": {
-                        "deep-extend": "^0.5.1",
-                        "ini": "~1.3.0",
-                        "minimist": "^1.2.0",
-                        "strip-json-comments": "~2.0.1"
+                        "deep-extend": "0.5.1",
+                        "ini": "1.3.5",
+                        "minimist": "1.2.0",
+                        "strip-json-comments": "2.0.1"
                     },
                     "dependencies": {
                         "minimist": {
@@ -11078,107 +11059,107 @@
                     "version": "1.0.7",
                     "bundled": true,
                     "requires": {
-                        "mute-stream": "~0.0.4"
+                        "mute-stream": "0.0.7"
                     }
                 },
                 "read-cmd-shim": {
                     "version": "1.0.5",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2"
+                        "graceful-fs": "4.2.3"
                     }
                 },
                 "read-installed": {
                     "version": "4.0.3",
                     "bundled": true,
                     "requires": {
-                        "debuglog": "^1.0.1",
-                        "graceful-fs": "^4.1.2",
-                        "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"
+                        "debuglog": "1.0.1",
+                        "graceful-fs": "4.2.3",
+                        "read-package-json": "2.1.1",
+                        "readdir-scoped-modules": "1.1.0",
+                        "semver": "5.7.1",
+                        "slide": "1.1.6",
+                        "util-extend": "1.0.3"
                     }
                 },
                 "read-package-json": {
                     "version": "2.1.1",
                     "bundled": true,
                     "requires": {
-                        "glob": "^7.1.1",
-                        "graceful-fs": "^4.1.2",
-                        "json-parse-better-errors": "^1.0.1",
-                        "normalize-package-data": "^2.0.0",
-                        "npm-normalize-package-bin": "^1.0.0"
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.3",
+                        "json-parse-better-errors": "1.0.2",
+                        "normalize-package-data": "2.5.0",
+                        "npm-normalize-package-bin": "1.0.1"
                     }
                 },
                 "read-package-tree": {
                     "version": "5.3.1",
                     "bundled": true,
                     "requires": {
-                        "read-package-json": "^2.0.0",
-                        "readdir-scoped-modules": "^1.0.0",
-                        "util-promisify": "^2.1.0"
+                        "read-package-json": "2.1.1",
+                        "readdir-scoped-modules": "1.1.0",
+                        "util-promisify": "2.1.0"
                     }
                 },
                 "readable-stream": {
                     "version": "3.4.0",
                     "bundled": true,
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.4",
+                        "string_decoder": "1.2.0",
+                        "util-deprecate": "1.0.2"
                     }
                 },
                 "readdir-scoped-modules": {
                     "version": "1.1.0",
                     "bundled": true,
                     "requires": {
-                        "debuglog": "^1.0.1",
-                        "dezalgo": "^1.0.0",
-                        "graceful-fs": "^4.1.2",
-                        "once": "^1.3.0"
+                        "debuglog": "1.0.1",
+                        "dezalgo": "1.0.3",
+                        "graceful-fs": "4.2.3",
+                        "once": "1.4.0"
                     }
                 },
                 "registry-auth-token": {
                     "version": "3.3.2",
                     "bundled": true,
                     "requires": {
-                        "rc": "^1.1.6",
-                        "safe-buffer": "^5.0.1"
+                        "rc": "1.2.7",
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "registry-url": {
                     "version": "3.1.0",
                     "bundled": true,
                     "requires": {
-                        "rc": "^1.0.1"
+                        "rc": "1.2.7"
                     }
                 },
                 "request": {
                     "version": "2.88.0",
                     "bundled": true,
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "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.3"
                     }
                 },
                 "require-directory": {
@@ -11201,14 +11182,14 @@
                     "version": "2.6.3",
                     "bundled": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "run-queue": {
                     "version": "1.0.3",
                     "bundled": true,
                     "requires": {
-                        "aproba": "^1.1.1"
+                        "aproba": "1.2.0"
                     },
                     "dependencies": {
                         "aproba": {
@@ -11233,7 +11214,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "semver": "^5.0.3"
+                        "semver": "5.7.1"
                     }
                 },
                 "set-blocking": {
@@ -11244,14 +11225,14 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.2"
+                        "graceful-fs": "4.2.3"
                     }
                 },
                 "shebang-command": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "shebang-regex": "^1.0.0"
+                        "shebang-regex": "1.0.0"
                     }
                 },
                 "shebang-regex": {
@@ -11275,22 +11256,22 @@
                     "bundled": true,
                     "requires": {
                         "ip": "1.1.5",
-                        "smart-buffer": "^4.1.0"
+                        "smart-buffer": "4.1.0"
                     }
                 },
                 "socks-proxy-agent": {
                     "version": "4.0.2",
                     "bundled": true,
                     "requires": {
-                        "agent-base": "~4.2.1",
-                        "socks": "~2.3.2"
+                        "agent-base": "4.2.1",
+                        "socks": "2.3.3"
                     },
                     "dependencies": {
                         "agent-base": {
                             "version": "4.2.1",
                             "bundled": true,
                             "requires": {
-                                "es6-promisify": "^5.0.0"
+                                "es6-promisify": "5.0.0"
                             }
                         }
                     }
@@ -11303,16 +11284,16 @@
                     "version": "2.1.3",
                     "bundled": true,
                     "requires": {
-                        "from2": "^1.3.0",
-                        "stream-iterate": "^1.1.0"
+                        "from2": "1.3.0",
+                        "stream-iterate": "1.2.0"
                     },
                     "dependencies": {
                         "from2": {
                             "version": "1.3.0",
                             "bundled": true,
                             "requires": {
-                                "inherits": "~2.0.1",
-                                "readable-stream": "~1.1.10"
+                                "inherits": "2.0.4",
+                                "readable-stream": "1.1.14"
                             }
                         },
                         "isarray": {
@@ -11323,10 +11304,10 @@
                             "version": "1.1.14",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.1",
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
                                 "isarray": "0.0.1",
-                                "string_decoder": "~0.10.x"
+                                "string_decoder": "0.10.31"
                             }
                         },
                         "string_decoder": {
@@ -11339,8 +11320,8 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "spdx-expression-parse": "^3.0.0",
-                        "spdx-license-ids": "^3.0.0"
+                        "spdx-expression-parse": "3.0.0",
+                        "spdx-license-ids": "3.0.3"
                     }
                 },
                 "spdx-exceptions": {
@@ -11351,8 +11332,8 @@
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "spdx-exceptions": "^2.1.0",
-                        "spdx-license-ids": "^3.0.0"
+                        "spdx-exceptions": "2.1.0",
+                        "spdx-license-ids": "3.0.3"
                     }
                 },
                 "spdx-license-ids": {
@@ -11367,58 +11348,58 @@
                     "version": "1.14.2",
                     "bundled": true,
                     "requires": {
-                        "asn1": "~0.2.3",
-                        "assert-plus": "^1.0.0",
-                        "bcrypt-pbkdf": "^1.0.0",
-                        "dashdash": "^1.12.0",
-                        "ecc-jsbn": "~0.1.1",
-                        "getpass": "^0.1.1",
-                        "jsbn": "~0.1.0",
-                        "safer-buffer": "^2.0.2",
-                        "tweetnacl": "~0.14.0"
+                        "asn1": "0.2.4",
+                        "assert-plus": "1.0.0",
+                        "bcrypt-pbkdf": "1.0.2",
+                        "dashdash": "1.14.1",
+                        "ecc-jsbn": "0.1.2",
+                        "getpass": "0.1.7",
+                        "jsbn": "0.1.1",
+                        "safer-buffer": "2.1.2",
+                        "tweetnacl": "0.14.5"
                     }
                 },
                 "ssri": {
                     "version": "6.0.1",
                     "bundled": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1"
+                        "figgy-pudding": "3.5.1"
                     }
                 },
                 "stream-each": {
                     "version": "1.2.2",
                     "bundled": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "stream-shift": "^1.0.0"
+                        "end-of-stream": "1.4.1",
+                        "stream-shift": "1.0.0"
                     }
                 },
                 "stream-iterate": {
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "readable-stream": "^2.1.5",
-                        "stream-shift": "^1.0.0"
+                        "readable-stream": "2.3.6",
+                        "stream-shift": "1.0.0"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -11435,8 +11416,8 @@
                     "version": "2.1.1",
                     "bundled": true,
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     },
                     "dependencies": {
                         "ansi-regex": {
@@ -11451,7 +11432,7 @@
                             "version": "4.0.0",
                             "bundled": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -11460,7 +11441,7 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "safe-buffer": "~5.1.0"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "stringify-package": {
@@ -11471,7 +11452,7 @@
                     "version": "3.0.1",
                     "bundled": true,
                     "requires": {
-                        "ansi-regex": "^2.0.0"
+                        "ansi-regex": "2.1.1"
                     }
                 },
                 "strip-eof": {
@@ -11486,28 +11467,28 @@
                     "version": "5.4.0",
                     "bundled": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "tar": {
                     "version": "4.4.13",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "chownr": "1.1.3",
+                        "fs-minipass": "1.2.7",
+                        "minipass": "2.9.0",
+                        "minizlib": "1.3.3",
+                        "mkdirp": "0.5.1",
+                        "safe-buffer": "5.1.2",
+                        "yallist": "3.0.3"
                     },
                     "dependencies": {
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "^5.1.2",
-                                "yallist": "^3.0.0"
+                                "safe-buffer": "5.1.2",
+                                "yallist": "3.0.3"
                             }
                         }
                     }
@@ -11516,7 +11497,7 @@
                     "version": "1.2.0",
                     "bundled": true,
                     "requires": {
-                        "execa": "^0.7.0"
+                        "execa": "0.7.0"
                     }
                 },
                 "text-table": {
@@ -11531,28 +11512,28 @@
                     "version": "2.0.3",
                     "bundled": true,
                     "requires": {
-                        "readable-stream": "^2.1.5",
-                        "xtend": "~4.0.1"
+                        "readable-stream": "2.3.6",
+                        "xtend": "4.0.1"
                     },
                     "dependencies": {
                         "readable-stream": {
                             "version": "2.3.6",
                             "bundled": true,
                             "requires": {
-                                "core-util-is": "~1.0.0",
-                                "inherits": "~2.0.3",
-                                "isarray": "~1.0.0",
-                                "process-nextick-args": "~2.0.0",
-                                "safe-buffer": "~5.1.1",
-                                "string_decoder": "~1.1.1",
-                                "util-deprecate": "~1.0.1"
+                                "core-util-is": "1.0.2",
+                                "inherits": "2.0.4",
+                                "isarray": "1.0.0",
+                                "process-nextick-args": "2.0.0",
+                                "safe-buffer": "5.1.2",
+                                "string_decoder": "1.1.1",
+                                "util-deprecate": "1.0.2"
                             }
                         },
                         "string_decoder": {
                             "version": "1.1.1",
                             "bundled": true,
                             "requires": {
-                                "safe-buffer": "~5.1.0"
+                                "safe-buffer": "5.1.2"
                             }
                         }
                     }
@@ -11569,15 +11550,15 @@
                     "version": "2.4.3",
                     "bundled": true,
                     "requires": {
-                        "psl": "^1.1.24",
-                        "punycode": "^1.4.1"
+                        "psl": "1.1.29",
+                        "punycode": "1.4.1"
                     }
                 },
                 "tunnel-agent": {
                     "version": "0.6.0",
                     "bundled": true,
                     "requires": {
-                        "safe-buffer": "^5.0.1"
+                        "safe-buffer": "5.1.2"
                     }
                 },
                 "tweetnacl": {
@@ -11601,21 +11582,21 @@
                     "version": "1.1.1",
                     "bundled": true,
                     "requires": {
-                        "unique-slug": "^2.0.0"
+                        "unique-slug": "2.0.0"
                     }
                 },
                 "unique-slug": {
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "imurmurhash": "^0.1.4"
+                        "imurmurhash": "0.1.4"
                     }
                 },
                 "unique-string": {
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "crypto-random-string": "^1.0.0"
+                        "crypto-random-string": "1.0.0"
                     }
                 },
                 "unpipe": {
@@ -11630,23 +11611,23 @@
                     "version": "2.5.0",
                     "bundled": true,
                     "requires": {
-                        "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"
+                        "boxen": "1.3.0",
+                        "chalk": "2.4.1",
+                        "configstore": "3.1.2",
+                        "import-lazy": "2.1.0",
+                        "is-ci": "1.1.0",
+                        "is-installed-globally": "0.1.0",
+                        "is-npm": "1.0.0",
+                        "latest-version": "3.1.0",
+                        "semver-diff": "2.1.0",
+                        "xdg-basedir": "3.0.0"
                     }
                 },
                 "url-parse-lax": {
                     "version": "1.0.0",
                     "bundled": true,
                     "requires": {
-                        "prepend-http": "^1.0.1"
+                        "prepend-http": "1.0.4"
                     }
                 },
                 "util-deprecate": {
@@ -11661,7 +11642,7 @@
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "object.getownpropertydescriptors": "^2.0.3"
+                        "object.getownpropertydescriptors": "2.0.3"
                     }
                 },
                 "uuid": {
@@ -11672,38 +11653,38 @@
                     "version": "3.0.4",
                     "bundled": true,
                     "requires": {
-                        "spdx-correct": "^3.0.0",
-                        "spdx-expression-parse": "^3.0.0"
+                        "spdx-correct": "3.0.0",
+                        "spdx-expression-parse": "3.0.0"
                     }
                 },
                 "validate-npm-package-name": {
                     "version": "3.0.0",
                     "bundled": true,
                     "requires": {
-                        "builtins": "^1.0.3"
+                        "builtins": "1.0.3"
                     }
                 },
                 "verror": {
                     "version": "1.10.0",
                     "bundled": true,
                     "requires": {
-                        "assert-plus": "^1.0.0",
+                        "assert-plus": "1.0.0",
                         "core-util-is": "1.0.2",
-                        "extsprintf": "^1.2.0"
+                        "extsprintf": "1.3.0"
                     }
                 },
                 "wcwidth": {
                     "version": "1.0.1",
                     "bundled": true,
                     "requires": {
-                        "defaults": "^1.0.3"
+                        "defaults": "1.0.3"
                     }
                 },
                 "which": {
                     "version": "1.3.1",
                     "bundled": true,
                     "requires": {
-                        "isexe": "^2.0.0"
+                        "isexe": "2.0.0"
                     }
                 },
                 "which-module": {
@@ -11714,16 +11695,16 @@
                     "version": "1.1.2",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^1.0.2"
+                        "string-width": "1.0.2"
                     },
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -11732,31 +11713,31 @@
                     "version": "2.0.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^2.1.1"
+                        "string-width": "2.1.1"
                     }
                 },
                 "worker-farm": {
                     "version": "1.7.0",
                     "bundled": true,
                     "requires": {
-                        "errno": "~0.1.7"
+                        "errno": "0.1.7"
                     }
                 },
                 "wrap-ansi": {
                     "version": "2.1.0",
                     "bundled": true,
                     "requires": {
-                        "string-width": "^1.0.1",
-                        "strip-ansi": "^3.0.1"
+                        "string-width": "1.0.2",
+                        "strip-ansi": "3.0.1"
                     },
                     "dependencies": {
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
                             "requires": {
-                                "code-point-at": "^1.0.0",
-                                "is-fullwidth-code-point": "^1.0.0",
-                                "strip-ansi": "^3.0.0"
+                                "code-point-at": "1.1.0",
+                                "is-fullwidth-code-point": "1.0.0",
+                                "strip-ansi": "3.0.1"
                             }
                         }
                     }
@@ -11769,9 +11750,9 @@
                     "version": "2.4.3",
                     "bundled": true,
                     "requires": {
-                        "graceful-fs": "^4.1.11",
-                        "imurmurhash": "^0.1.4",
-                        "signal-exit": "^3.0.2"
+                        "graceful-fs": "4.2.3",
+                        "imurmurhash": "0.1.4",
+                        "signal-exit": "3.0.2"
                     }
                 },
                 "xdg-basedir": {
@@ -11794,18 +11775,18 @@
                     "version": "11.0.0",
                     "bundled": true,
                     "requires": {
-                        "cliui": "^4.0.0",
-                        "decamelize": "^1.1.1",
-                        "find-up": "^2.1.0",
-                        "get-caller-file": "^1.0.1",
-                        "os-locale": "^2.0.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^1.0.1",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^2.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^3.2.1",
-                        "yargs-parser": "^9.0.2"
+                        "cliui": "4.1.0",
+                        "decamelize": "1.2.0",
+                        "find-up": "2.1.0",
+                        "get-caller-file": "1.0.2",
+                        "os-locale": "2.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "1.0.1",
+                        "set-blocking": "2.0.0",
+                        "string-width": "2.1.1",
+                        "which-module": "2.0.0",
+                        "y18n": "3.2.1",
+                        "yargs-parser": "9.0.2"
                     },
                     "dependencies": {
                         "y18n": {
@@ -11818,7 +11799,7 @@
                     "version": "9.0.2",
                     "bundled": true,
                     "requires": {
-                        "camelcase": "^4.1.0"
+                        "camelcase": "4.1.0"
                     }
                 }
             }
@@ -11828,7 +11809,7 @@
             "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
             "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
             "requires": {
-                "npm-normalize-package-bin": "^1.0.1"
+                "npm-normalize-package-bin": "1.0.1"
             }
         },
         "npm-normalize-package-bin": {
@@ -11841,8 +11822,8 @@
             "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.7.tgz",
             "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==",
             "requires": {
-                "ignore-walk": "^3.0.1",
-                "npm-bundled": "^1.0.1"
+                "ignore-walk": "3.0.3",
+                "npm-bundled": "1.1.1"
             }
         },
         "npm-run-path": {
@@ -11850,7 +11831,7 @@
             "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
             "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
             "requires": {
-                "path-key": "^2.0.0"
+                "path-key": "2.0.1"
             }
         },
         "npmlog": {
@@ -11858,10 +11839,10 @@
             "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
             "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
             "requires": {
-                "are-we-there-yet": "~1.1.2",
-                "console-control-strings": "~1.1.0",
-                "gauge": "~2.7.3",
-                "set-blocking": "~2.0.0"
+                "are-we-there-yet": "1.1.5",
+                "console-control-strings": "1.1.0",
+                "gauge": "2.7.4",
+                "set-blocking": "2.0.0"
             }
         },
         "nth-check": {
@@ -11869,7 +11850,7 @@
             "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
             "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
             "requires": {
-                "boolbase": "~1.0.0"
+                "boolbase": "1.0.0"
             }
         },
         "number-is-nan": {
@@ -11908,9 +11889,9 @@
             "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
             "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
             "requires": {
-                "copy-descriptor": "^0.1.0",
-                "define-property": "^0.2.5",
-                "kind-of": "^3.0.3"
+                "copy-descriptor": "0.1.1",
+                "define-property": "0.2.5",
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "define-property": {
@@ -11918,7 +11899,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "kind-of": {
@@ -11926,7 +11907,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -11975,10 +11956,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -11988,7 +11969,7 @@
             "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
             "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
             "requires": {
-                "isobject": "^3.0.0"
+                "isobject": "3.0.1"
             }
         },
         "object.assign": {
@@ -11996,10 +11977,10 @@
             "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
             "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
             "requires": {
-                "define-properties": "^1.1.2",
-                "function-bind": "^1.1.1",
-                "has-symbols": "^1.0.0",
-                "object-keys": "^1.0.11"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1",
+                "has-symbols": "1.0.0",
+                "object-keys": "1.1.1"
             }
         },
         "object.getownpropertydescriptors": {
@@ -12007,8 +11988,8 @@
             "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
             "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
             "requires": {
-                "define-properties": "^1.1.2",
-                "es-abstract": "^1.5.1"
+                "define-properties": "1.1.3",
+                "es-abstract": "1.16.0"
             }
         },
         "object.pick": {
@@ -12016,7 +11997,7 @@
             "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
             "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
             "requires": {
-                "isobject": "^3.0.1"
+                "isobject": "3.0.1"
             }
         },
         "obuf": {
@@ -12043,7 +12024,7 @@
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
             "requires": {
-                "wrappy": "1"
+                "wrappy": "1.0.2"
             }
         },
         "opn": {
@@ -12052,7 +12033,7 @@
             "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
             "dev": true,
             "requires": {
-                "is-wsl": "^1.1.0"
+                "is-wsl": "1.1.0"
             }
         },
         "optionator": {
@@ -12061,12 +12042,12 @@
             "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
             "dev": true,
             "requires": {
-                "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"
+                "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"
             }
         },
         "orderedmap": {
@@ -12080,7 +12061,7 @@
             "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
             "dev": true,
             "requires": {
-                "url-parse": "^1.4.3"
+                "url-parse": "1.4.7"
             }
         },
         "os-browserify": {
@@ -12091,7 +12072,7 @@
         },
         "os-homedir": {
             "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+            "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
             "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
         },
         "os-locale": {
@@ -12099,12 +12080,12 @@
             "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
             "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
             "requires": {
-                "lcid": "^1.0.0"
+                "lcid": "1.0.0"
             }
         },
         "os-tmpdir": {
             "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+            "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
             "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
         },
         "osenv": {
@@ -12112,8 +12093,8 @@
             "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
             "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
             "requires": {
-                "os-homedir": "^1.0.0",
-                "os-tmpdir": "^1.0.0"
+                "os-homedir": "1.0.2",
+                "os-tmpdir": "1.0.2"
             }
         },
         "p-defer": {
@@ -12138,7 +12119,7 @@
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
             "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
             "requires": {
-                "p-try": "^2.0.0"
+                "p-try": "2.2.0"
             },
             "dependencies": {
                 "p-try": {
@@ -12153,7 +12134,7 @@
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
             "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
             "requires": {
-                "p-limit": "^1.1.0"
+                "p-limit": "1.3.0"
             },
             "dependencies": {
                 "p-limit": {
@@ -12161,7 +12142,7 @@
                     "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
                     "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
                     "requires": {
-                        "p-try": "^1.0.0"
+                        "p-try": "1.0.0"
                     }
                 }
             }
@@ -12178,7 +12159,7 @@
             "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
             "dev": true,
             "requires": {
-                "retry": "^0.12.0"
+                "retry": "0.12.0"
             }
         },
         "p-try": {
@@ -12191,10 +12172,10 @@
             "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
             "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
             "requires": {
-                "got": "^6.7.1",
-                "registry-auth-token": "^3.0.1",
-                "registry-url": "^3.0.3",
-                "semver": "^5.1.0"
+                "got": "6.7.1",
+                "registry-auth-token": "3.4.0",
+                "registry-url": "3.1.0",
+                "semver": "5.7.0"
             }
         },
         "pako": {
@@ -12209,9 +12190,9 @@
             "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
             "dev": true,
             "requires": {
-                "cyclist": "~0.2.2",
-                "inherits": "^2.0.3",
-                "readable-stream": "^2.1.5"
+                "cyclist": "0.2.2",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "parent-module": {
@@ -12219,7 +12200,7 @@
             "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
             "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
             "requires": {
-                "callsites": "^3.0.0"
+                "callsites": "3.1.0"
             }
         },
         "parse-asn1": {
@@ -12227,12 +12208,12 @@
             "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz",
             "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==",
             "requires": {
-                "asn1.js": "^4.0.0",
-                "browserify-aes": "^1.0.0",
-                "create-hash": "^1.1.0",
-                "evp_bytestokey": "^1.0.0",
-                "pbkdf2": "^3.0.3",
-                "safe-buffer": "^5.1.1"
+                "asn1.js": "4.10.1",
+                "browserify-aes": "1.2.0",
+                "create-hash": "1.2.0",
+                "evp_bytestokey": "1.0.3",
+                "pbkdf2": "3.0.17",
+                "safe-buffer": "5.1.2"
             }
         },
         "parse-json": {
@@ -12240,10 +12221,10 @@
             "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
             "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
             "requires": {
-                "@babel/code-frame": "^7.0.0",
-                "error-ex": "^1.3.1",
-                "json-parse-better-errors": "^1.0.1",
-                "lines-and-columns": "^1.1.6"
+                "@babel/code-frame": "7.5.5",
+                "error-ex": "1.3.2",
+                "json-parse-better-errors": "1.0.2",
+                "lines-and-columns": "1.1.6"
             }
         },
         "parse-passwd": {
@@ -12263,7 +12244,7 @@
             "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
             "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
             "requires": {
-                "better-assert": "~1.0.0"
+                "better-assert": "1.0.2"
             }
         },
         "parseuri": {
@@ -12271,7 +12252,7 @@
             "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
             "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
             "requires": {
-                "better-assert": "~1.0.0"
+                "better-assert": "1.0.2"
             }
         },
         "parseurl": {
@@ -12289,7 +12270,7 @@
             "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
             "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
             "requires": {
-                "passport-strategy": "1.x.x",
+                "passport-strategy": "1.0.0",
                 "pause": "0.0.1"
             }
         },
@@ -12298,7 +12279,7 @@
             "resolved": "https://registry.npmjs.org/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz",
             "integrity": "sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==",
             "requires": {
-                "passport-oauth2": "1.x.x"
+                "passport-oauth2": "1.5.0"
             }
         },
         "passport-local": {
@@ -12306,7 +12287,7 @@
             "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
             "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
             "requires": {
-                "passport-strategy": "1.x.x"
+                "passport-strategy": "1.0.0"
             }
         },
         "passport-oauth2": {
@@ -12314,11 +12295,11 @@
             "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz",
             "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==",
             "requires": {
-                "base64url": "3.x.x",
-                "oauth": "0.9.x",
-                "passport-strategy": "1.x.x",
-                "uid2": "0.0.x",
-                "utils-merge": "1.x.x"
+                "base64url": "3.0.1",
+                "oauth": "0.9.15",
+                "passport-strategy": "1.0.0",
+                "uid2": "0.0.3",
+                "utils-merge": "1.0.1"
             }
         },
         "passport-strategy": {
@@ -12344,7 +12325,7 @@
         },
         "path-is-absolute": {
             "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
             "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
         "path-is-inside": {
@@ -12372,9 +12353,9 @@
             "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
             "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
             "requires": {
-                "graceful-fs": "^4.1.2",
-                "pify": "^2.0.0",
-                "pinkie-promise": "^2.0.0"
+                "graceful-fs": "4.2.0",
+                "pify": "2.3.0",
+                "pinkie-promise": "2.0.1"
             }
         },
         "pathval": {
@@ -12392,11 +12373,11 @@
             "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
             "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
             "requires": {
-                "create-hash": "^1.1.2",
-                "create-hmac": "^1.1.4",
-                "ripemd160": "^2.0.1",
-                "safe-buffer": "^5.0.1",
-                "sha.js": "^2.4.8"
+                "create-hash": "1.2.0",
+                "create-hmac": "1.1.7",
+                "ripemd160": "2.0.2",
+                "safe-buffer": "5.1.2",
+                "sha.js": "2.4.11"
             }
         },
         "pdf-parse": {
@@ -12404,8 +12385,8 @@
             "resolved": "https://registry.npmjs.org/pdf-parse/-/pdf-parse-1.1.1.tgz",
             "integrity": "sha512-v6ZJ/efsBpGrGGknjtq9J/oC8tZWq0KWL5vQrk2GlzLEQPUDB1ex+13Rmidl1neNN358Jn9EHZw5y07FFtaC7A==",
             "requires": {
-                "debug": "^3.1.0",
-                "node-ensure": "^0.0.0"
+                "debug": "3.2.6",
+                "node-ensure": "0.0.0"
             },
             "dependencies": {
                 "debug": {
@@ -12413,7 +12394,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -12428,8 +12409,8 @@
             "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.2.228.tgz",
             "integrity": "sha512-W5LhYPMS2UKX0ELIa4u+CFCMoox5qQNQElt0bAK2mwz1V8jZL0rvLao+0tBujce84PK6PvWG36Nwr7agCCWFGQ==",
             "requires": {
-                "node-ensure": "^0.0.0",
-                "worker-loader": "^2.0.0"
+                "node-ensure": "0.0.0",
+                "worker-loader": "2.0.0"
             }
         },
         "performance-now": {
@@ -12457,7 +12438,7 @@
             "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
             "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
             "requires": {
-                "pinkie": "^2.0.0"
+                "pinkie": "2.0.4"
             }
         },
         "pipe-functions": {
@@ -12471,7 +12452,7 @@
             "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
             "dev": true,
             "requires": {
-                "find-up": "^2.1.0"
+                "find-up": "2.1.0"
             }
         },
         "pn": {
@@ -12491,9 +12472,9 @@
             "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
             "dev": true,
             "requires": {
-                "async": "^2.6.2",
-                "debug": "^3.1.1",
-                "mkdirp": "^0.5.1"
+                "async": "2.6.3",
+                "debug": "3.2.6",
+                "mkdirp": "0.5.1"
             },
             "dependencies": {
                 "debug": {
@@ -12502,7 +12483,7 @@
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -12524,9 +12505,9 @@
             "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==",
             "dev": true,
             "requires": {
-                "chalk": "^2.4.2",
-                "source-map": "^0.6.1",
-                "supports-color": "^6.1.0"
+                "chalk": "2.4.2",
+                "source-map": "0.6.1",
+                "supports-color": "6.1.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -12535,7 +12516,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -12544,9 +12525,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     },
                     "dependencies": {
                         "supports-color": {
@@ -12555,7 +12536,7 @@
                             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                             "dev": true,
                             "requires": {
-                                "has-flag": "^3.0.0"
+                                "has-flag": "3.0.0"
                             }
                         }
                     }
@@ -12572,7 +12553,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -12583,7 +12564,7 @@
             "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.5"
+                "postcss": "7.0.17"
             }
         },
         "postcss-modules-local-by-default": {
@@ -12592,9 +12573,9 @@
             "integrity": "sha512-oLUV5YNkeIBa0yQl7EYnxMgy4N6noxmiwZStaEJUSe2xPMcdNc8WmBQuQCx18H5psYbVxz8zoHk0RAAYZXP9gA==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.6",
-                "postcss-selector-parser": "^6.0.0",
-                "postcss-value-parser": "^3.3.1"
+                "postcss": "7.0.17",
+                "postcss-selector-parser": "6.0.2",
+                "postcss-value-parser": "3.3.1"
             }
         },
         "postcss-modules-scope": {
@@ -12603,8 +12584,8 @@
             "integrity": "sha512-91Rjps0JnmtUB0cujlc8KIKCsJXWjzuxGeT/+Q2i2HXKZ7nBUeF9YQTZZTNvHVoNYj1AthsjnGLtqDUE0Op79A==",
             "dev": true,
             "requires": {
-                "postcss": "^7.0.6",
-                "postcss-selector-parser": "^6.0.0"
+                "postcss": "7.0.17",
+                "postcss-selector-parser": "6.0.2"
             }
         },
         "postcss-modules-values": {
@@ -12613,8 +12594,8 @@
             "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==",
             "dev": true,
             "requires": {
-                "icss-replace-symbols": "^1.1.0",
-                "postcss": "^7.0.6"
+                "icss-replace-symbols": "1.1.0",
+                "postcss": "7.0.17"
             }
         },
         "postcss-selector-parser": {
@@ -12623,9 +12604,9 @@
             "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==",
             "dev": true,
             "requires": {
-                "cssesc": "^3.0.0",
-                "indexes-of": "^1.0.1",
-                "uniq": "^1.0.1"
+                "cssesc": "3.0.0",
+                "indexes-of": "1.0.1",
+                "uniq": "1.0.1"
             }
         },
         "postcss-value-parser": {
@@ -12639,21 +12620,21 @@
             "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-5.3.3.tgz",
             "integrity": "sha512-GV+nsUXuPW2p8Zy7SarF/2W/oiK8bFQgJcncoJ0d7kRpekEA0ftChjfEaF9/Y+QJEc/wFR7RAEa8lYByuUIe2g==",
             "requires": {
-                "detect-libc": "^1.0.3",
-                "expand-template": "^2.0.3",
+                "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"
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "napi-build-utils": "1.0.1",
+                "node-abi": "2.13.0",
+                "noop-logger": "0.1.1",
+                "npmlog": "4.1.2",
+                "pump": "3.0.0",
+                "rc": "1.2.8",
+                "simple-get": "3.0.3",
+                "tar-fs": "2.0.0",
+                "tunnel-agent": "0.6.0",
+                "which-pm-runs": "1.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -12666,8 +12647,8 @@
                     "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 }
             }
@@ -12693,12 +12674,12 @@
             "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-4.1.1.tgz",
             "integrity": "sha512-42LqKZqTLxH/UvAZ2/cKhAsR4G/Y6B7i7fI2qtQu9hRBK4YjS6gqO+QRtwTjvojUx4+/+JuOMzLoFyRecT9qRw==",
             "requires": {
-                "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"
+                "any-promise": "1.3.0",
+                "deepmerge": "4.0.0",
+                "inherits": "2.0.3",
+                "next-tick": "1.0.0",
+                "request": "2.88.0",
+                "stream-parser": "0.3.1"
             },
             "dependencies": {
                 "assert-plus": {
@@ -12726,9 +12707,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "har-validator": {
@@ -12736,8 +12717,8 @@
                     "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
                     "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
                     "requires": {
-                        "ajv": "^6.5.5",
-                        "har-schema": "^2.0.0"
+                        "ajv": "6.10.2",
+                        "har-schema": "2.0.0"
                     }
                 },
                 "http-signature": {
@@ -12745,9 +12726,9 @@
                     "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
                     "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
                     "requires": {
-                        "assert-plus": "^1.0.0",
-                        "jsprim": "^1.2.2",
-                        "sshpk": "^1.7.0"
+                        "assert-plus": "1.0.0",
+                        "jsprim": "1.4.1",
+                        "sshpk": "1.16.1"
                     }
                 },
                 "oauth-sign": {
@@ -12765,26 +12746,26 @@
                     "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
                     "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
                     "requires": {
-                        "aws-sign2": "~0.7.0",
-                        "aws4": "^1.8.0",
-                        "caseless": "~0.12.0",
-                        "combined-stream": "~1.0.6",
-                        "extend": "~3.0.2",
-                        "forever-agent": "~0.6.1",
-                        "form-data": "~2.3.2",
-                        "har-validator": "~5.1.0",
-                        "http-signature": "~1.2.0",
-                        "is-typedarray": "~1.0.0",
-                        "isstream": "~0.1.2",
-                        "json-stringify-safe": "~5.0.1",
-                        "mime-types": "~2.1.19",
-                        "oauth-sign": "~0.9.0",
-                        "performance-now": "^2.1.0",
-                        "qs": "~6.5.2",
-                        "safe-buffer": "^5.1.2",
-                        "tough-cookie": "~2.4.3",
-                        "tunnel-agent": "^0.6.0",
-                        "uuid": "^3.3.2"
+                        "aws-sign2": "0.7.0",
+                        "aws4": "1.9.0",
+                        "caseless": "0.12.0",
+                        "combined-stream": "1.0.8",
+                        "extend": "3.0.2",
+                        "forever-agent": "0.6.1",
+                        "form-data": "2.3.3",
+                        "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.24",
+                        "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.3"
                     }
                 }
             }
@@ -12805,7 +12786,7 @@
             "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
             "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
             "requires": {
-                "asap": "~2.0.3"
+                "asap": "2.0.6"
             }
         },
         "promise-inflight": {
@@ -12819,9 +12800,9 @@
             "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
             "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==",
             "requires": {
-                "loose-envify": "^1.4.0",
-                "object-assign": "^4.1.1",
-                "react-is": "^16.8.1"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "react-is": "16.8.6"
             }
         },
         "prop-types-extra": {
@@ -12829,8 +12810,8 @@
             "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.0.tgz",
             "integrity": "sha512-QFyuDxvMipmIVKD2TwxLVPzMnO4e5oOf1vr3tJIomL8E7d0lr6phTHd5nkPhFIzTD1idBLLEPeylL9g+rrTzRg==",
             "requires": {
-                "react-is": "^16.3.2",
-                "warning": "^3.0.0"
+                "react-is": "16.8.6",
+                "warning": "3.0.0"
             }
         },
         "prosemirror-commands": {
@@ -12838,9 +12819,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.3.tgz",
             "integrity": "sha512-YVbKwTR4likoyhuwIUC9egbzHvnFrFUNbiesB0DB/HZ8hBcopQ42Tb4KGlYrS3n+pNDTFObN73CLFY6mYLN2IQ==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.8.2",
+                "prosemirror-state": "1.3.2",
+                "prosemirror-transform": "1.2.3"
             }
         },
         "prosemirror-dropcursor": {
@@ -12848,9 +12829,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.2.tgz",
             "integrity": "sha512-4c94OUGyobGnwcQI70OXyMhE/9T4aTgjU+CHxkd5c7D+jH/J0mKM/lk+jneFVKt7+E4/M0D9HzRPifu8U28Thw==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.1.0",
-                "prosemirror-view": "^1.1.0"
+                "prosemirror-state": "1.3.2",
+                "prosemirror-transform": "1.2.3",
+                "prosemirror-view": "1.13.7"
             }
         },
         "prosemirror-example-setup": {
@@ -12858,15 +12839,15 @@
             "resolved": "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.1.2.tgz",
             "integrity": "sha512-MTpIMyqk08jFnzxeRMCinCEMtVSTUtxKgQBGxfCbVe9C6zIOqp9qZZJz5Ojaad1GETySyuj8+OIHHvQsIaaaGQ==",
             "requires": {
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-dropcursor": "^1.0.0",
-                "prosemirror-gapcursor": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-inputrules": "^1.0.0",
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-menu": "^1.0.0",
-                "prosemirror-schema-list": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
+                "prosemirror-commands": "1.1.3",
+                "prosemirror-dropcursor": "1.3.2",
+                "prosemirror-gapcursor": "1.1.2",
+                "prosemirror-history": "1.1.3",
+                "prosemirror-inputrules": "1.1.2",
+                "prosemirror-keymap": "1.1.3",
+                "prosemirror-menu": "1.1.2",
+                "prosemirror-schema-list": "1.1.2",
+                "prosemirror-state": "1.3.2"
             }
         },
         "prosemirror-find-replace": {
@@ -12879,10 +12860,10 @@
             "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.2.tgz",
             "integrity": "sha512-Z+eqk6RysZVxidGWN5aWoSTbn5bTHf1XZ+nQJVwUSdwdBVkfQMFdTHgfrXA8W5MhHHdNg/EEEYG3z3Zi/vE2QQ==",
             "requires": {
-                "prosemirror-keymap": "^1.0.0",
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-view": "^1.0.0"
+                "prosemirror-keymap": "1.1.3",
+                "prosemirror-model": "1.8.2",
+                "prosemirror-state": "1.3.2",
+                "prosemirror-view": "1.13.7"
             }
         },
         "prosemirror-history": {
@@ -12890,9 +12871,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz",
             "integrity": "sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==",
             "requires": {
-                "prosemirror-state": "^1.2.2",
-                "prosemirror-transform": "^1.0.0",
-                "rope-sequence": "^1.3.0"
+                "prosemirror-state": "1.3.2",
+                "prosemirror-transform": "1.2.3",
+                "rope-sequence": "1.3.2"
             }
         },
         "prosemirror-inputrules": {
@@ -12900,8 +12881,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.2.tgz",
             "integrity": "sha512-Ja5Z3BWestlHYGvtSGqyvxMeB8QEuBjlHM8YnKtLGUXMDp965qdDV4goV8lJb17kIWHk7e7JNj6Catuoa3302g==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-state": "1.3.2",
+                "prosemirror-transform": "1.2.3"
             }
         },
         "prosemirror-keymap": {
@@ -12909,8 +12890,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.3.tgz",
             "integrity": "sha512-PRA4NzkUMzV/NFf5pyQ6tmlIHiW/qjQ1kGWUlV2rF/dvlOxtpGpTEjIMhWgLuMf+HiDEFnUEP7uhYXu+t+491g==",
             "requires": {
-                "prosemirror-state": "^1.0.0",
-                "w3c-keyname": "^2.2.0"
+                "prosemirror-state": "1.3.2",
+                "w3c-keyname": "2.2.2"
             }
         },
         "prosemirror-menu": {
@@ -12918,10 +12899,10 @@
             "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.1.2.tgz",
             "integrity": "sha512-iAPBMnxaj0AXzqgzxrJPrjo5njIqUaDQjyS17R/vb6zIBnEtH1ZDPanrmZnYkBEFvvM4fBtzDZSQct5iJNTcDQ==",
             "requires": {
-                "crel": "^3.1.0",
-                "prosemirror-commands": "^1.0.0",
-                "prosemirror-history": "^1.0.0",
-                "prosemirror-state": "^1.0.0"
+                "crel": "3.1.0",
+                "prosemirror-commands": "1.1.3",
+                "prosemirror-history": "1.1.3",
+                "prosemirror-state": "1.3.2"
             }
         },
         "prosemirror-model": {
@@ -12929,7 +12910,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.8.2.tgz",
             "integrity": "sha512-piffokzW7opZVCjf/9YaoXvTC0g7zMRWKJib1hpphPfC+4x6ZXe5CiExgycoWZJe59VxxP7uHX8aFiwg2i9mUQ==",
             "requires": {
-                "orderedmap": "^1.1.0"
+                "orderedmap": "1.1.0"
             }
         },
         "prosemirror-schema-basic": {
@@ -12937,7 +12918,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.1.2.tgz",
             "integrity": "sha512-G4q8WflNsR1Q33QAV4MQO0xWrHLOJ+BQcKswGXMy626wlQj6c/1n1v4eC9ns+h2y1r/fJHZEgSZnsNhm9lbrDw==",
             "requires": {
-                "prosemirror-model": "^1.2.0"
+                "prosemirror-model": "1.8.2"
             }
         },
         "prosemirror-schema-list": {
@@ -12945,8 +12926,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.1.2.tgz",
             "integrity": "sha512-dgM9PwtM4twa5WsgSYMB+J8bwjnR43DAD3L9MsR9rKm/nZR5Y85xcjB7gusVMSsbQ2NomMZF03RE6No6mTnclQ==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.8.2",
+                "prosemirror-transform": "1.2.3"
             }
         },
         "prosemirror-state": {
@@ -12954,8 +12935,8 @@
             "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.2.tgz",
             "integrity": "sha512-t/JqE3aR0SV9QrzFVkAXsQwsgrQBNs/BDbcFH20RssW0xauqNNdjTXxy/J/kM7F+0zYi6+BRmz7cMMQQFU3mwQ==",
             "requires": {
-                "prosemirror-model": "^1.0.0",
-                "prosemirror-transform": "^1.0.0"
+                "prosemirror-model": "1.8.2",
+                "prosemirror-transform": "1.2.3"
             }
         },
         "prosemirror-transform": {
@@ -12963,7 +12944,7 @@
             "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.2.3.tgz",
             "integrity": "sha512-PUfayeskQfuUBXktvL6207ZWRwHBFNPNPiek4fR+LgCPnBofuEb2+L0FfbNtrAwffHVs6M3DaFvJB1W2VQdV0A==",
             "requires": {
-                "prosemirror-model": "^1.0.0"
+                "prosemirror-model": "1.8.2"
             }
         },
         "prosemirror-view": {
@@ -12971,9 +12952,9 @@
             "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.13.7.tgz",
             "integrity": "sha512-P9Vrxe5/PJ68rJi/665NYAdj9hs9iXvvDo4OxD4G0rVmt4lna/n+H7BW1gT/ItDXdNR+LiU8c1mf/TX5RkJbxA==",
             "requires": {
-                "prosemirror-model": "^1.1.0",
-                "prosemirror-state": "^1.0.0",
-                "prosemirror-transform": "^1.1.0"
+                "prosemirror-model": "1.8.2",
+                "prosemirror-state": "1.3.2",
+                "prosemirror-transform": "1.2.3"
             }
         },
         "proxy-addr": {
@@ -12981,7 +12962,7 @@
             "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
             "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
             "requires": {
-                "forwarded": "~0.1.2",
+                "forwarded": "0.1.2",
                 "ipaddr.js": "1.9.0"
             }
         },
@@ -13011,12 +12992,12 @@
             "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
             "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
             "requires": {
-                "bn.js": "^4.1.0",
-                "browserify-rsa": "^4.0.0",
-                "create-hash": "^1.1.0",
-                "parse-asn1": "^5.0.0",
-                "randombytes": "^2.0.1",
-                "safe-buffer": "^5.1.2"
+                "bn.js": "4.11.8",
+                "browserify-rsa": "4.0.1",
+                "create-hash": "1.2.0",
+                "parse-asn1": "5.1.4",
+                "randombytes": "2.1.0",
+                "safe-buffer": "5.1.2"
             }
         },
         "pug": {
@@ -13024,14 +13005,14 @@
             "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
             "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
             "requires": {
-                "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"
+                "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"
             }
         },
         "pug-attrs": {
@@ -13039,9 +13020,9 @@
             "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.4.tgz",
             "integrity": "sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==",
             "requires": {
-                "constantinople": "^3.0.1",
-                "js-stringify": "^1.0.1",
-                "pug-runtime": "^2.0.5"
+                "constantinople": "3.1.2",
+                "js-stringify": "1.0.2",
+                "pug-runtime": "2.0.5"
             }
         },
         "pug-code-gen": {
@@ -13049,14 +13030,14 @@
             "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
             "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
             "requires": {
-                "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"
+                "constantinople": "3.1.2",
+                "doctypes": "1.1.0",
+                "js-stringify": "1.0.2",
+                "pug-attrs": "2.0.4",
+                "pug-error": "1.3.3",
+                "pug-runtime": "2.0.5",
+                "void-elements": "2.0.1",
+                "with": "5.1.1"
             }
         },
         "pug-error": {
@@ -13069,13 +13050,13 @@
             "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
             "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
             "requires": {
-                "clean-css": "^4.1.11",
-                "constantinople": "^3.0.1",
+                "clean-css": "4.2.1",
+                "constantinople": "3.1.2",
                 "jstransformer": "1.0.0",
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8",
-                "resolve": "^1.1.6",
-                "uglify-js": "^2.6.1"
+                "pug-error": "1.3.3",
+                "pug-walk": "1.1.8",
+                "resolve": "1.11.1",
+                "uglify-js": "2.8.29"
             }
         },
         "pug-lexer": {
@@ -13083,9 +13064,9 @@
             "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.1.0.tgz",
             "integrity": "sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==",
             "requires": {
-                "character-parser": "^2.1.1",
-                "is-expression": "^3.0.0",
-                "pug-error": "^1.3.3"
+                "character-parser": "2.2.0",
+                "is-expression": "3.0.0",
+                "pug-error": "1.3.3"
             }
         },
         "pug-linker": {
@@ -13093,8 +13074,8 @@
             "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
             "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
             "requires": {
-                "pug-error": "^1.3.3",
-                "pug-walk": "^1.1.8"
+                "pug-error": "1.3.3",
+                "pug-walk": "1.1.8"
             }
         },
         "pug-load": {
@@ -13102,8 +13083,8 @@
             "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
             "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
             "requires": {
-                "object-assign": "^4.1.0",
-                "pug-walk": "^1.1.8"
+                "object-assign": "4.1.1",
+                "pug-walk": "1.1.8"
             }
         },
         "pug-parser": {
@@ -13111,7 +13092,7 @@
             "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
             "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
             "requires": {
-                "pug-error": "^1.3.3",
+                "pug-error": "1.3.3",
                 "token-stream": "0.0.1"
             }
         },
@@ -13125,7 +13106,7 @@
             "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
             "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
             "requires": {
-                "pug-error": "^1.3.3"
+                "pug-error": "1.3.3"
             }
         },
         "pug-walk": {
@@ -13139,8 +13120,8 @@
             "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
             "dev": true,
             "requires": {
-                "end-of-stream": "^1.1.0",
-                "once": "^1.3.1"
+                "end-of-stream": "1.4.1",
+                "once": "1.4.0"
             }
         },
         "pumpify": {
@@ -13149,9 +13130,9 @@
             "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
             "dev": true,
             "requires": {
-                "duplexify": "^3.6.0",
-                "inherits": "^2.0.3",
-                "pump": "^2.0.0"
+                "duplexify": "3.7.1",
+                "inherits": "2.0.3",
+                "pump": "2.0.1"
             }
         },
         "punycode": {
@@ -13174,9 +13155,9 @@
             "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.9.0.tgz",
             "integrity": "sha512-KG4bhCFYapExLsUHrFt+kQVEegF2agm4cpF/VNc6pZVthIfCc/GK8t8VyNIE3nyXG9DK3Tf2EGkxjR6/uRdYsA==",
             "requires": {
-                "decode-uri-component": "^0.2.0",
-                "split-on-first": "^1.0.0",
-                "strict-uri-encode": "^2.0.0"
+                "decode-uri-component": "0.2.0",
+                "split-on-first": "1.1.0",
+                "strict-uri-encode": "2.0.0"
             }
         },
         "querystring": {
@@ -13207,7 +13188,7 @@
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
             "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
             "requires": {
-                "safe-buffer": "^5.1.0"
+                "safe-buffer": "5.1.2"
             }
         },
         "randomfill": {
@@ -13215,8 +13196,8 @@
             "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
             "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
             "requires": {
-                "randombytes": "^2.0.5",
-                "safe-buffer": "^5.1.0"
+                "randombytes": "2.1.0",
+                "safe-buffer": "5.1.2"
             }
         },
         "range-parser": {
@@ -13240,8 +13221,8 @@
             "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-1.0.0.tgz",
             "integrity": "sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA==",
             "requires": {
-                "loader-utils": "^1.1.0",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -13249,9 +13230,9 @@
                     "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -13261,10 +13242,10 @@
             "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
             "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
             "requires": {
-                "deep-extend": "^0.6.0",
-                "ini": "~1.3.0",
-                "minimist": "^1.2.0",
-                "strip-json-comments": "~2.0.1"
+                "deep-extend": "0.6.0",
+                "ini": "1.3.5",
+                "minimist": "1.2.0",
+                "strip-json-comments": "2.0.1"
             },
             "dependencies": {
                 "minimist": {
@@ -13279,9 +13260,9 @@
             "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-1.9.0.tgz",
             "integrity": "sha512-Isas+egaK6qSk64jaEw4GgPStY4umYDbT7ZY93bZF1Af+b/JEsKsJdNOU2qG3WI0Z6tXo2DDq0kJCv8Yhu0zww==",
             "requires": {
-                "classnames": "^2.2.1",
-                "prop-types": "^15.5.6",
-                "react-lifecycles-compat": "^3.0.4"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "react": {
@@ -13289,9 +13270,9 @@
             "resolved": "https://registry.npmjs.org/react/-/react-16.12.0.tgz",
             "integrity": "sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1",
-                "prop-types": "^15.6.2"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "prop-types": "15.7.2"
             }
         },
         "react-anime": {
@@ -13299,8 +13280,8 @@
             "resolved": "https://registry.npmjs.org/react-anime/-/react-anime-2.3.2.tgz",
             "integrity": "sha512-Wh9p1EdU5NTc2lyemHlaGG0QKuUYhpeGbh1Auw14Be+vukIkbCIaBMOyFya0Q7SIjSPzTNNpIgnD3oIv8TXWiw==",
             "requires": {
-                "animejs": "^3.1.0",
-                "lodash.isequal": "^4.5.0"
+                "animejs": "3.1.0",
+                "lodash.isequal": "4.5.0"
             }
         },
         "react-autosuggest": {
@@ -13308,9 +13289,9 @@
             "resolved": "https://registry.npmjs.org/react-autosuggest/-/react-autosuggest-9.4.3.tgz",
             "integrity": "sha512-wFbp5QpgFQRfw9cwKvcgLR8theikOUkv8PFsuLYqI2PUgVlx186Cz8MYt5bLxculi+jxGGUUVt+h0esaBZZouw==",
             "requires": {
-                "prop-types": "^15.5.10",
-                "react-autowhatever": "^10.1.2",
-                "shallow-equal": "^1.0.0"
+                "prop-types": "15.7.2",
+                "react-autowhatever": "10.2.0",
+                "shallow-equal": "1.2.0"
             }
         },
         "react-autowhatever": {
@@ -13318,9 +13299,9 @@
             "resolved": "https://registry.npmjs.org/react-autowhatever/-/react-autowhatever-10.2.0.tgz",
             "integrity": "sha512-dqHH4uqiJldPMbL8hl/i2HV4E8FMTDEdVlOIbRqYnJi0kTpWseF9fJslk/KS9pGDnm80JkYzVI+nzFjnOG/u+g==",
             "requires": {
-                "prop-types": "^15.5.8",
-                "react-themeable": "^1.1.0",
-                "section-iterator": "^2.0.0"
+                "prop-types": "15.7.2",
+                "react-themeable": "1.1.0",
+                "section-iterator": "2.0.0"
             }
         },
         "react-bootstrap": {
@@ -13328,21 +13309,21 @@
             "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.0-beta.16.tgz",
             "integrity": "sha512-wjb+3CwviDWAaz4O3gQpd2XMDNqbOiqOOzpLm5aLPcp1wTsQsVRhyM+rTPmO3hYU8auA2eNpTYLz08/fAcMqDA==",
             "requires": {
-                "@babel/runtime": "^7.4.2",
-                "@restart/context": "^2.1.4",
-                "@restart/hooks": "^0.3.11",
-                "@types/react": "^16.8.23",
-                "classnames": "^2.2.6",
-                "dom-helpers": "^5.1.2",
-                "invariant": "^2.2.4",
-                "keycode": "^2.2.0",
-                "popper.js": "^1.16.0",
-                "prop-types": "^15.7.2",
-                "prop-types-extra": "^1.1.0",
-                "react-overlays": "^2.1.0",
-                "react-transition-group": "^4.0.0",
-                "uncontrollable": "^7.0.0",
-                "warning": "^4.0.3"
+                "@babel/runtime": "7.5.5",
+                "@restart/context": "2.1.4",
+                "@restart/hooks": "0.3.19",
+                "@types/react": "16.9.17",
+                "classnames": "2.2.6",
+                "dom-helpers": "5.1.3",
+                "invariant": "2.2.4",
+                "keycode": "2.2.0",
+                "popper.js": "1.16.0",
+                "prop-types": "15.7.2",
+                "prop-types-extra": "1.1.0",
+                "react-overlays": "2.1.0",
+                "react-transition-group": "4.3.0",
+                "uncontrollable": "7.1.1",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "csstype": {
@@ -13355,8 +13336,8 @@
                     "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz",
                     "integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==",
                     "requires": {
-                        "@babel/runtime": "^7.6.3",
-                        "csstype": "^2.6.7"
+                        "@babel/runtime": "7.7.7",
+                        "csstype": "2.6.8"
                     },
                     "dependencies": {
                         "@babel/runtime": {
@@ -13364,7 +13345,7 @@
                             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz",
                             "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==",
                             "requires": {
-                                "regenerator-runtime": "^0.13.2"
+                                "regenerator-runtime": "0.13.3"
                             }
                         }
                     }
@@ -13374,10 +13355,10 @@
                     "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.3.0.tgz",
                     "integrity": "sha512-1qRV1ZuVSdxPlPf4O8t7inxUGpdyO5zG9IoNfJxSO0ImU2A1YWkEQvFPuIPZmMLkg5hYs7vv5mMOyfgSkvAwvw==",
                     "requires": {
-                        "@babel/runtime": "^7.5.5",
-                        "dom-helpers": "^5.0.1",
-                        "loose-envify": "^1.4.0",
-                        "prop-types": "^15.6.2"
+                        "@babel/runtime": "7.5.5",
+                        "dom-helpers": "5.1.3",
+                        "loose-envify": "1.4.0",
+                        "prop-types": "15.7.2"
                     }
                 },
                 "uncontrollable": {
@@ -13385,10 +13366,10 @@
                     "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
                     "integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
                     "requires": {
-                        "@babel/runtime": "^7.6.3",
-                        "@types/react": "^16.9.11",
-                        "invariant": "^2.2.4",
-                        "react-lifecycles-compat": "^3.0.4"
+                        "@babel/runtime": "7.7.7",
+                        "@types/react": "16.9.17",
+                        "invariant": "2.2.4",
+                        "react-lifecycles-compat": "3.0.4"
                     },
                     "dependencies": {
                         "@babel/runtime": {
@@ -13396,7 +13377,7 @@
                             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz",
                             "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==",
                             "requires": {
-                                "regenerator-runtime": "^0.13.2"
+                                "regenerator-runtime": "0.13.3"
                             }
                         }
                     }
@@ -13406,7 +13387,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13421,12 +13402,12 @@
             "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.17.3.tgz",
             "integrity": "sha512-1dtO8LqAVotPIChlmo6kLtFS1FP89ll8/OiA8EcFRDR+ntcK+0ukJgByuIQHRtzvigf26dV5HklnxDIvhON9VQ==",
             "requires": {
-                "@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"
+                "@icons/material": "0.2.4",
+                "lodash": "4.17.15",
+                "material-colors": "1.2.6",
+                "prop-types": "15.7.2",
+                "reactcss": "1.2.3",
+                "tinycolor2": "1.4.1"
             }
         },
         "react-dimensions": {
@@ -13434,7 +13415,7 @@
             "resolved": "https://registry.npmjs.org/react-dimensions/-/react-dimensions-1.3.1.tgz",
             "integrity": "sha512-go5vMuGUxaB5PiTSIk+ZfAxLbHwcIgIfLhkBZ2SIMQjaCgnpttxa30z5ijEzfDjeOCTGRpxvkzcmE4Vt4Ppvyw==",
             "requires": {
-                "element-resize-event": "^2.0.4"
+                "element-resize-event": "2.0.9"
             }
         },
         "react-dom": {
@@ -13442,10 +13423,10 @@
             "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.12.0.tgz",
             "integrity": "sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1",
-                "prop-types": "^15.6.2",
-                "scheduler": "^0.18.0"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1",
+                "prop-types": "15.7.2",
+                "scheduler": "0.18.0"
             }
         },
         "react-golden-layout": {
@@ -13453,9 +13434,9 @@
             "resolved": "https://registry.npmjs.org/react-golden-layout/-/react-golden-layout-1.0.6.tgz",
             "integrity": "sha512-KZQ17Bnd+LfyCqe2scVMznrGKTciX3VwoT3y4xn3Qok9hknCvVXZfXe2RSX5zNG7FlLJzWt0VWqy8qZBHpQVuQ==",
             "requires": {
-                "golden-layout": "^1.5.9",
-                "react": "^16.3.0",
-                "react-dom": "^16.3.0"
+                "golden-layout": "1.5.9",
+                "react": "16.12.0",
+                "react-dom": "16.12.0"
             }
         },
         "react-image-lightbox-with-rotate": {
@@ -13463,9 +13444,9 @@
             "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==",
             "requires": {
-                "blueimp-load-image": "^2.19.0",
-                "prop-types": "^15.6.1",
-                "react-modal": "^3.4.4"
+                "blueimp-load-image": "2.24.0",
+                "prop-types": "15.7.2",
+                "react-modal": "3.9.1"
             }
         },
         "react-is": {
@@ -13478,8 +13459,8 @@
             "resolved": "https://registry.npmjs.org/react-jsx-parser/-/react-jsx-parser-1.21.0.tgz",
             "integrity": "sha512-3ZYS0+Fiz1hx1owMDvA6skoYnISdsdthKEMLmcoqQ2CF+LzBKnYK/GtMJ5lKKz0AfZiNpsBq8qK7Av2ZE6vEVQ==",
             "requires": {
-                "acorn": "^7.1.0",
-                "acorn-jsx": "^5.1.0"
+                "acorn": "7.1.0",
+                "acorn-jsx": "5.1.0"
             },
             "dependencies": {
                 "acorn": {
@@ -13499,10 +13480,10 @@
             "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.3.0.tgz",
             "integrity": "sha512-dwAvmiOeblj5Dvpnk8Jm7Q8B4THF/f1l1HtKVi0XDecsG6LXwGvzV5R1H32kq3TW6RW64OAf5aoQxpIgLa4z8A==",
             "requires": {
-                "@babel/runtime": "^7.2.0",
-                "get-node-dimensions": "^1.2.1",
-                "prop-types": "^15.6.2",
-                "resize-observer-polyfill": "^1.5.0"
+                "@babel/runtime": "7.5.5",
+                "get-node-dimensions": "1.2.1",
+                "prop-types": "15.7.2",
+                "resize-observer-polyfill": "1.5.1"
             }
         },
         "react-modal": {
@@ -13510,10 +13491,10 @@
             "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.9.1.tgz",
             "integrity": "sha512-k+TUkhGWpIVHLsEyjNmlyOYL0Uz03fNZvlkhCImd1h+6fhNgTi6H6jexVXPVhD2LMMDzJyfugxMN+APN/em+eQ==",
             "requires": {
-                "exenv": "^1.2.0",
-                "prop-types": "^15.5.10",
-                "react-lifecycles-compat": "^3.0.0",
-                "warning": "^4.0.3"
+                "exenv": "1.2.2",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "warning": {
@@ -13521,7 +13502,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13531,8 +13512,8 @@
             "resolved": "https://registry.npmjs.org/react-mosaic/-/react-mosaic-0.0.20.tgz",
             "integrity": "sha1-pSSr8uzyi5r2sh1NNQ/veCLvMJ4=",
             "requires": {
-                "prop-types": "^15.6.0",
-                "threads": "^0.8.0"
+                "prop-types": "15.7.2",
+                "threads": "0.8.1"
             }
         },
         "react-overlays": {
@@ -13540,13 +13521,13 @@
             "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-2.1.0.tgz",
             "integrity": "sha512-tHPGTZosbQSo82yb9x4YCsmJJtspKvAPL5kXVnyoB2Z5UoAU3VetIuh2VblfVT408us5nLJd9uDtwI3xWDHS6w==",
             "requires": {
-                "@babel/runtime": "^7.4.5",
-                "@restart/hooks": "^0.3.12",
-                "dom-helpers": "^5.1.0",
-                "popper.js": "^1.15.0",
-                "prop-types": "^15.7.2",
-                "uncontrollable": "^7.0.0",
-                "warning": "^4.0.3"
+                "@babel/runtime": "7.5.5",
+                "@restart/hooks": "0.3.19",
+                "dom-helpers": "5.1.3",
+                "popper.js": "1.16.0",
+                "prop-types": "15.7.2",
+                "uncontrollable": "7.1.1",
+                "warning": "4.0.3"
             },
             "dependencies": {
                 "csstype": {
@@ -13559,8 +13540,8 @@
                     "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.3.tgz",
                     "integrity": "sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==",
                     "requires": {
-                        "@babel/runtime": "^7.6.3",
-                        "csstype": "^2.6.7"
+                        "@babel/runtime": "7.7.7",
+                        "csstype": "2.6.8"
                     },
                     "dependencies": {
                         "@babel/runtime": {
@@ -13568,7 +13549,7 @@
                             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz",
                             "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==",
                             "requires": {
-                                "regenerator-runtime": "^0.13.2"
+                                "regenerator-runtime": "0.13.3"
                             }
                         }
                     }
@@ -13578,10 +13559,10 @@
                     "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
                     "integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
                     "requires": {
-                        "@babel/runtime": "^7.6.3",
-                        "@types/react": "^16.9.11",
-                        "invariant": "^2.2.4",
-                        "react-lifecycles-compat": "^3.0.4"
+                        "@babel/runtime": "7.7.7",
+                        "@types/react": "16.9.17",
+                        "invariant": "2.2.4",
+                        "react-lifecycles-compat": "3.0.4"
                     },
                     "dependencies": {
                         "@babel/runtime": {
@@ -13589,7 +13570,7 @@
                             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz",
                             "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==",
                             "requires": {
-                                "regenerator-runtime": "^0.13.2"
+                                "regenerator-runtime": "0.13.3"
                             }
                         }
                     }
@@ -13599,7 +13580,7 @@
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
                     "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
                     "requires": {
-                        "loose-envify": "^1.0.0"
+                        "loose-envify": "1.4.0"
                     }
                 }
             }
@@ -13609,8 +13590,8 @@
             "resolved": "https://registry.npmjs.org/react-simple-dropdown/-/react-simple-dropdown-3.2.3.tgz",
             "integrity": "sha512-NmyyvA0D4wph5ctzkn8U4wmblOacavJMl9gTOhQR3v8I997mc1FL1NFKkj3Mx+HNysBKRD/HI+kpxXCAgXumPw==",
             "requires": {
-                "classnames": "^2.1.2",
-                "prop-types": "^15.5.8"
+                "classnames": "2.2.6",
+                "prop-types": "15.7.2"
             }
         },
         "react-split-pane": {
@@ -13618,9 +13599,9 @@
             "resolved": "https://registry.npmjs.org/react-split-pane/-/react-split-pane-0.1.89.tgz",
             "integrity": "sha512-bGEiOevi6nBE1evEJOsZjd5A7plLboFAU4+HGASWWVm94XUg7QdsuPInGOB+5Ym4RtY3TZCpmUvLe6qQmrZUOg==",
             "requires": {
-                "prop-types": "^15.5.10",
-                "react-lifecycles-compat": "^3.0.4",
-                "react-style-proptype": "^3.0.0"
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4",
+                "react-style-proptype": "3.2.2"
             }
         },
         "react-style-proptype": {
@@ -13628,7 +13609,7 @@
             "resolved": "https://registry.npmjs.org/react-style-proptype/-/react-style-proptype-3.2.2.tgz",
             "integrity": "sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==",
             "requires": {
-                "prop-types": "^15.5.4"
+                "prop-types": "15.7.2"
             }
         },
         "react-table": {
@@ -13636,9 +13617,9 @@
             "resolved": "https://registry.npmjs.org/react-table/-/react-table-6.11.5.tgz",
             "integrity": "sha512-LM+AS9v//7Y7lAlgTWW/cW6Sn5VOb3EsSkKQfQTzOW8FngB1FUskLLNEVkAYsTX9LjOWR3QlGjykJqCE6eXT/g==",
             "requires": {
-                "@types/react-table": "^6.8.5",
-                "classnames": "^2.2.5",
-                "react-is": "^16.8.1"
+                "@types/react-table": "6.8.6",
+                "classnames": "2.2.6",
+                "react-is": "16.8.6"
             }
         },
         "react-themeable": {
@@ -13646,7 +13627,7 @@
             "resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
             "integrity": "sha1-fURm3ZsrX6dQWHJ4JenxUro3mg4=",
             "requires": {
-                "object-assign": "^3.0.0"
+                "object-assign": "3.0.0"
             },
             "dependencies": {
                 "object-assign": {
@@ -13661,10 +13642,10 @@
             "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
             "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
             "requires": {
-                "dom-helpers": "^3.4.0",
-                "loose-envify": "^1.4.0",
-                "prop-types": "^15.6.2",
-                "react-lifecycles-compat": "^3.0.4"
+                "dom-helpers": "3.4.0",
+                "loose-envify": "1.4.0",
+                "prop-types": "15.7.2",
+                "react-lifecycles-compat": "3.0.4"
             }
         },
         "reactcss": {
@@ -13672,7 +13653,7 @@
             "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
             "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
             "requires": {
-                "lodash": "^4.0.1"
+                "lodash": "4.17.15"
             }
         },
         "read-pkg": {
@@ -13680,9 +13661,9 @@
             "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
             "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
             "requires": {
-                "load-json-file": "^1.0.0",
-                "normalize-package-data": "^2.3.2",
-                "path-type": "^1.0.0"
+                "load-json-file": "1.1.0",
+                "normalize-package-data": "2.5.0",
+                "path-type": "1.1.0"
             }
         },
         "read-pkg-up": {
@@ -13690,8 +13671,8 @@
             "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
             "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
             "requires": {
-                "find-up": "^1.0.0",
-                "read-pkg": "^1.0.0"
+                "find-up": "1.1.2",
+                "read-pkg": "1.1.0"
             },
             "dependencies": {
                 "find-up": {
@@ -13699,8 +13680,8 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
                     "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
                     "requires": {
-                        "path-exists": "^2.0.0",
-                        "pinkie-promise": "^2.0.0"
+                        "path-exists": "2.1.0",
+                        "pinkie-promise": "2.0.1"
                     }
                 },
                 "path-exists": {
@@ -13708,7 +13689,7 @@
                     "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
                     "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
                     "requires": {
-                        "pinkie-promise": "^2.0.0"
+                        "pinkie-promise": "2.0.1"
                     }
                 }
             }
@@ -13718,13 +13699,13 @@
             "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
             "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
             "requires": {
-                "core-util-is": "~1.0.0",
-                "inherits": "~2.0.3",
-                "isarray": "~1.0.0",
-                "process-nextick-args": "~2.0.0",
-                "safe-buffer": "~5.1.1",
-                "string_decoder": "~1.1.1",
-                "util-deprecate": "~1.0.1"
+                "core-util-is": "1.0.2",
+                "inherits": "2.0.3",
+                "isarray": "1.0.0",
+                "process-nextick-args": "2.0.1",
+                "safe-buffer": "5.1.2",
+                "string_decoder": "1.1.1",
+                "util-deprecate": "1.0.2"
             }
         },
         "readdirp": {
@@ -13732,9 +13713,9 @@
             "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
             "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
             "requires": {
-                "graceful-fs": "^4.1.11",
-                "micromatch": "^3.1.10",
-                "readable-stream": "^2.0.2"
+                "graceful-fs": "4.2.0",
+                "micromatch": "3.1.10",
+                "readable-stream": "2.3.6"
             }
         },
         "readline": {
@@ -13748,9 +13729,9 @@
             "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=",
             "requires": {
                 "ast-types": "0.9.6",
-                "esprima": "~3.1.0",
-                "private": "~0.1.5",
-                "source-map": "~0.5.0"
+                "esprima": "3.1.3",
+                "private": "0.1.8",
+                "source-map": "0.5.7"
             },
             "dependencies": {
                 "esprima": {
@@ -13765,7 +13746,7 @@
             "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
             "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
             "requires": {
-                "resolve": "^1.1.6"
+                "resolve": "1.11.1"
             }
         },
         "redent": {
@@ -13773,8 +13754,8 @@
             "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
             "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
             "requires": {
-                "indent-string": "^2.1.0",
-                "strip-indent": "^1.0.1"
+                "indent-string": "2.1.0",
+                "strip-indent": "1.0.1"
             }
         },
         "reduce-flatten": {
@@ -13792,8 +13773,8 @@
             "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
             "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
             "requires": {
-                "extend-shallow": "^3.0.2",
-                "safe-regex": "^1.1.0"
+                "extend-shallow": "3.0.2",
+                "safe-regex": "1.1.0"
             }
         },
         "regexp-clone": {
@@ -13807,8 +13788,8 @@
             "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
             "dev": true,
             "requires": {
-                "define-properties": "^1.1.3",
-                "es-abstract": "^1.17.0-next.1"
+                "define-properties": "1.1.3",
+                "es-abstract": "1.17.0"
             },
             "dependencies": {
                 "es-abstract": {
@@ -13817,17 +13798,17 @@
                     "integrity": "sha512-yYkE07YF+6SIBmg1MsJ9dlub5L48Ek7X0qz+c/CPCHS9EBXfESorzng4cJQjJW5/pB6vDF41u7F8vUhLVDqIug==",
                     "dev": true,
                     "requires": {
-                        "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"
+                        "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"
                     }
                 },
                 "es-to-primitive": {
@@ -13836,9 +13817,9 @@
                     "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
                     "dev": true,
                     "requires": {
-                        "is-callable": "^1.1.4",
-                        "is-date-object": "^1.0.1",
-                        "is-symbol": "^1.0.2"
+                        "is-callable": "1.1.5",
+                        "is-date-object": "1.0.1",
+                        "is-symbol": "1.0.2"
                     }
                 },
                 "has-symbols": {
@@ -13859,7 +13840,7 @@
                     "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
                     "dev": true,
                     "requires": {
-                        "has": "^1.0.3"
+                        "has": "1.0.3"
                     }
                 },
                 "object-inspect": {
@@ -13874,8 +13855,8 @@
                     "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
                     "dev": true,
                     "requires": {
-                        "define-properties": "^1.1.3",
-                        "function-bind": "^1.1.1"
+                        "define-properties": "1.1.3",
+                        "function-bind": "1.1.1"
                     }
                 },
                 "string.prototype.trimright": {
@@ -13884,8 +13865,8 @@
                     "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
                     "dev": true,
                     "requires": {
-                        "define-properties": "^1.1.3",
-                        "function-bind": "^1.1.1"
+                        "define-properties": "1.1.3",
+                        "function-bind": "1.1.1"
                     }
                 }
             }
@@ -13895,8 +13876,8 @@
             "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
             "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
             "requires": {
-                "rc": "^1.1.6",
-                "safe-buffer": "^5.0.1"
+                "rc": "1.2.8",
+                "safe-buffer": "5.1.2"
             }
         },
         "registry-url": {
@@ -13904,7 +13885,7 @@
             "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
             "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
             "requires": {
-                "rc": "^1.0.1"
+                "rc": "1.2.8"
             }
         },
         "remove-trailing-separator": {
@@ -13927,7 +13908,7 @@
             "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
             "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
             "requires": {
-                "is-finite": "^1.0.0"
+                "is-finite": "1.0.2"
             }
         },
         "request": {
@@ -13935,26 +13916,26 @@
             "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
             "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
             "requires": {
-                "aws-sign2": "~0.7.0",
-                "aws4": "^1.8.0",
-                "caseless": "~0.12.0",
-                "combined-stream": "~1.0.6",
-                "extend": "~3.0.2",
-                "forever-agent": "~0.6.1",
-                "form-data": "~2.3.2",
-                "har-validator": "~5.1.0",
-                "http-signature": "~1.2.0",
-                "is-typedarray": "~1.0.0",
-                "isstream": "~0.1.2",
-                "json-stringify-safe": "~5.0.1",
-                "mime-types": "~2.1.19",
-                "oauth-sign": "~0.9.0",
-                "performance-now": "^2.1.0",
-                "qs": "~6.5.2",
-                "safe-buffer": "^5.1.2",
-                "tough-cookie": "~2.4.3",
-                "tunnel-agent": "^0.6.0",
-                "uuid": "^3.3.2"
+                "aws-sign2": "0.7.0",
+                "aws4": "1.9.0",
+                "caseless": "0.12.0",
+                "combined-stream": "1.0.8",
+                "extend": "3.0.2",
+                "forever-agent": "0.6.1",
+                "form-data": "2.3.3",
+                "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.24",
+                "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.3"
             },
             "dependencies": {
                 "form-data": {
@@ -13962,9 +13943,9 @@
                     "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
                     "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
                     "requires": {
-                        "asynckit": "^0.4.0",
-                        "combined-stream": "^1.0.6",
-                        "mime-types": "^2.1.12"
+                        "asynckit": "0.4.0",
+                        "combined-stream": "1.0.8",
+                        "mime-types": "2.1.24"
                     }
                 },
                 "qs": {
@@ -13979,10 +13960,10 @@
             "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz",
             "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==",
             "requires": {
-                "bluebird": "^3.5.0",
+                "bluebird": "3.7.2",
                 "request-promise-core": "1.1.3",
-                "stealthy-require": "^1.1.1",
-                "tough-cookie": "^2.3.3"
+                "stealthy-require": "1.1.1",
+                "tough-cookie": "2.4.3"
             }
         },
         "request-promise-core": {
@@ -13990,7 +13971,7 @@
             "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
             "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
             "requires": {
-                "lodash": "^4.17.15"
+                "lodash": "4.17.15"
             }
         },
         "request-promise-native": {
@@ -14000,8 +13981,8 @@
             "dev": true,
             "requires": {
                 "request-promise-core": "1.1.3",
-                "stealthy-require": "^1.1.1",
-                "tough-cookie": "^2.3.3"
+                "stealthy-require": "1.1.1",
+                "tough-cookie": "2.4.3"
             }
         },
         "require-directory": {
@@ -14019,8 +14000,8 @@
             "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
             "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
             "requires": {
-                "resolve-from": "^2.0.0",
-                "semver": "^5.1.0"
+                "resolve-from": "2.0.0",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "resolve-from": {
@@ -14041,18 +14022,18 @@
             "resolved": "https://registry.npmjs.org/resilient-server-session/-/resilient-server-session-1.1.2.tgz",
             "integrity": "sha512-eLoXxTc5bFOYH2JejSCYc2O8emoo80p2zOuwVVWVoK6/2NJBzLP8Yl7kU8m7tJDrOoqDSZGghsVD5ob9BbUgAQ==",
             "requires": {
-                "@types/chai": "^4.2.7",
-                "@types/mocha": "^5.2.7",
-                "@types/node": "^10.12.30",
-                "@types/request-promise": "^4.1.42",
-                "@types/uuid": "^3.4.6",
-                "chai": "^4.2.0",
-                "colors": "^1.4.0",
-                "jsonschema": "^1.2.5",
-                "mocha": "^7.0.0",
-                "request-promise": "^4.2.5",
-                "typescript": "^3.7.4",
-                "uuid": "^3.3.3"
+                "@types/chai": "4.2.7",
+                "@types/mocha": "5.2.7",
+                "@types/node": "10.17.13",
+                "@types/request-promise": "4.1.45",
+                "@types/uuid": "3.4.6",
+                "chai": "4.2.0",
+                "colors": "1.4.0",
+                "jsonschema": "1.2.5",
+                "mocha": "7.0.0",
+                "request-promise": "4.2.5",
+                "typescript": "3.7.4",
+                "uuid": "3.3.3"
             },
             "dependencies": {
                 "ansi-colors": {
@@ -14070,7 +14051,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "anymatch": {
@@ -14078,8 +14059,8 @@
                     "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
                     "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
                     "requires": {
-                        "normalize-path": "^3.0.0",
-                        "picomatch": "^2.0.4"
+                        "normalize-path": "3.0.0",
+                        "picomatch": "2.2.1"
                     }
                 },
                 "binary-extensions": {
@@ -14092,7 +14073,7 @@
                     "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
                     "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
                     "requires": {
-                        "fill-range": "^7.0.1"
+                        "fill-range": "7.0.1"
                     }
                 },
                 "camelcase": {
@@ -14105,14 +14086,14 @@
                     "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
                     "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
                     "requires": {
-                        "anymatch": "~3.1.1",
-                        "braces": "~3.0.2",
-                        "fsevents": "~2.1.1",
-                        "glob-parent": "~5.1.0",
-                        "is-binary-path": "~2.1.0",
-                        "is-glob": "~4.0.1",
-                        "normalize-path": "~3.0.0",
-                        "readdirp": "~3.2.0"
+                        "anymatch": "3.1.1",
+                        "braces": "3.0.2",
+                        "fsevents": "2.1.2",
+                        "glob-parent": "5.1.0",
+                        "is-binary-path": "2.1.0",
+                        "is-glob": "4.0.1",
+                        "normalize-path": "3.0.0",
+                        "readdirp": "3.2.0"
                     }
                 },
                 "cliui": {
@@ -14120,9 +14101,9 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "debug": {
@@ -14130,7 +14111,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.1"
                     }
                 },
                 "fill-range": {
@@ -14138,7 +14119,7 @@
                     "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
                     "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
                     "requires": {
-                        "to-regex-range": "^5.0.1"
+                        "to-regex-range": "5.0.1"
                     }
                 },
                 "find-up": {
@@ -14146,7 +14127,7 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "fsevents": {
@@ -14165,12 +14146,12 @@
                     "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
                     "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
                     "requires": {
-                        "fs.realpath": "^1.0.0",
-                        "inflight": "^1.0.4",
-                        "inherits": "2",
-                        "minimatch": "^3.0.4",
-                        "once": "^1.3.0",
-                        "path-is-absolute": "^1.0.0"
+                        "fs.realpath": "1.0.0",
+                        "inflight": "1.0.6",
+                        "inherits": "2.0.3",
+                        "minimatch": "3.0.4",
+                        "once": "1.4.0",
+                        "path-is-absolute": "1.0.1"
                     }
                 },
                 "glob-parent": {
@@ -14178,7 +14159,7 @@
                     "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
                     "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
                     "requires": {
-                        "is-glob": "^4.0.1"
+                        "is-glob": "4.0.1"
                     }
                 },
                 "he": {
@@ -14191,7 +14172,7 @@
                     "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
                     "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
                     "requires": {
-                        "binary-extensions": "^2.0.0"
+                        "binary-extensions": "2.0.0"
                     }
                 },
                 "is-fullwidth-code-point": {
@@ -14209,8 +14190,8 @@
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "mocha": {
@@ -14254,8 +14235,8 @@
                     "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
                     "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
                     "requires": {
-                        "object.getownpropertydescriptors": "^2.0.3",
-                        "semver": "^5.7.0"
+                        "object.getownpropertydescriptors": "2.0.3",
+                        "semver": "5.7.0"
                     }
                 },
                 "p-locate": {
@@ -14263,7 +14244,7 @@
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "readdirp": {
@@ -14271,7 +14252,7 @@
                     "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
                     "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
                     "requires": {
-                        "picomatch": "^2.0.4"
+                        "picomatch": "2.2.1"
                     }
                 },
                 "require-main-filename": {
@@ -14284,9 +14265,9 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -14294,7 +14275,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "supports-color": {
@@ -14302,7 +14283,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
                     "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "to-regex-range": {
@@ -14310,7 +14291,7 @@
                     "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
                     "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
                     "requires": {
-                        "is-number": "^7.0.0"
+                        "is-number": "7.0.0"
                     }
                 },
                 "which-module": {
@@ -14323,9 +14304,9 @@
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -14338,16 +14319,16 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
                     "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
                     "requires": {
-                        "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.1"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -14355,8 +14336,8 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -14371,7 +14352,7 @@
             "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
             "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
             "requires": {
-                "path-parse": "^1.0.6"
+                "path-parse": "1.0.6"
             }
         },
         "resolve-cwd": {
@@ -14380,7 +14361,7 @@
             "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
             "dev": true,
             "requires": {
-                "resolve-from": "^3.0.0"
+                "resolve-from": "3.0.0"
             }
         },
         "resolve-dir": {
@@ -14389,8 +14370,8 @@
             "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
             "dev": true,
             "requires": {
-                "expand-tilde": "^2.0.0",
-                "global-modules": "^1.0.0"
+                "expand-tilde": "2.0.2",
+                "global-modules": "1.0.0"
             },
             "dependencies": {
                 "global-modules": {
@@ -14399,9 +14380,9 @@
                     "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
                     "dev": true,
                     "requires": {
-                        "global-prefix": "^1.0.1",
-                        "is-windows": "^1.0.1",
-                        "resolve-dir": "^1.0.0"
+                        "global-prefix": "1.0.2",
+                        "is-windows": "1.0.2",
+                        "resolve-dir": "1.0.1"
                     }
                 }
             }
@@ -14433,7 +14414,7 @@
             "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
             "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
             "requires": {
-                "align-text": "^0.1.1"
+                "align-text": "0.1.4"
             }
         },
         "rimraf": {
@@ -14441,7 +14422,7 @@
             "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
             "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
             "requires": {
-                "glob": "^7.1.3"
+                "glob": "7.1.4"
             }
         },
         "ripemd160": {
@@ -14449,8 +14430,8 @@
             "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
             "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
             "requires": {
-                "hash-base": "^3.0.0",
-                "inherits": "^2.0.1"
+                "hash-base": "3.0.4",
+                "inherits": "2.0.3"
             }
         },
         "rope-sequence": {
@@ -14464,7 +14445,7 @@
             "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
             "dev": true,
             "requires": {
-                "aproba": "^1.1.1"
+                "aproba": "1.2.0"
             }
         },
         "safe-buffer": {
@@ -14474,10 +14455,10 @@
         },
         "safe-regex": {
             "version": "1.1.0",
-            "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+            "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
             "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "requires": {
-                "ret": "~0.1.10"
+                "ret": "0.1.15"
             }
         },
         "safer-buffer": {
@@ -14491,7 +14472,7 @@
             "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
             "optional": true,
             "requires": {
-                "sparse-bitfield": "^3.0.3"
+                "sparse-bitfield": "3.0.3"
             }
         },
         "sass-graph": {
@@ -14499,10 +14480,10 @@
             "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
             "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
             "requires": {
-                "glob": "^7.0.0",
-                "lodash": "^4.0.0",
-                "scss-tokenizer": "^0.2.3",
-                "yargs": "^7.0.0"
+                "glob": "7.1.4",
+                "lodash": "4.17.15",
+                "scss-tokenizer": "0.2.3",
+                "yargs": "7.1.0"
             }
         },
         "sass-loader": {
@@ -14511,11 +14492,11 @@
             "integrity": "sha512-tuU7+zm0pTCynKYHpdqaPpe+MMTQ76I9TPZ7i4/5dZsigE350shQWe5EZNl5dBidM49TPET75tNqRbcsUZWeNA==",
             "dev": true,
             "requires": {
-                "clone-deep": "^4.0.1",
-                "loader-utils": "^1.0.1",
-                "neo-async": "^2.5.0",
-                "pify": "^4.0.1",
-                "semver": "^6.3.0"
+                "clone-deep": "4.0.1",
+                "loader-utils": "1.2.3",
+                "neo-async": "2.6.1",
+                "pify": "4.0.1",
+                "semver": "6.3.0"
             },
             "dependencies": {
                 "pify": {
@@ -14543,7 +14524,7 @@
             "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
             "dev": true,
             "requires": {
-                "xmlchars": "^2.1.1"
+                "xmlchars": "2.2.0"
             }
         },
         "scheduler": {
@@ -14551,8 +14532,8 @@
             "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz",
             "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==",
             "requires": {
-                "loose-envify": "^1.1.0",
-                "object-assign": "^4.1.1"
+                "loose-envify": "1.4.0",
+                "object-assign": "4.1.1"
             }
         },
         "schema-utils": {
@@ -14560,8 +14541,8 @@
             "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
             "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
             "requires": {
-                "ajv": "^6.1.0",
-                "ajv-keywords": "^3.1.0"
+                "ajv": "6.10.2",
+                "ajv-keywords": "3.4.1"
             }
         },
         "scss-loader": {
@@ -14575,8 +14556,8 @@
             "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
             "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
             "requires": {
-                "js-base64": "^2.1.8",
-                "source-map": "^0.4.2"
+                "js-base64": "2.5.1",
+                "source-map": "0.4.4"
             },
             "dependencies": {
                 "source-map": {
@@ -14584,7 +14565,7 @@
                     "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
                     "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
                     "requires": {
-                        "amdefine": ">=0.0.4"
+                        "amdefine": "1.0.1"
                     }
                 }
             }
@@ -14619,7 +14600,7 @@
             "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
             "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
             "requires": {
-                "semver": "^5.0.3"
+                "semver": "5.7.0"
             }
         },
         "send": {
@@ -14628,18 +14609,18 @@
             "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
             "requires": {
                 "debug": "2.6.9",
-                "depd": "~1.1.2",
-                "destroy": "~1.0.4",
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "etag": "~1.8.1",
+                "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",
+                "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"
+                "on-finished": "2.3.0",
+                "range-parser": "1.2.1",
+                "statuses": "1.5.0"
             },
             "dependencies": {
                 "ms": {
@@ -14666,13 +14647,13 @@
             "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
             "dev": true,
             "requires": {
-                "accepts": "~1.3.4",
+                "accepts": "1.3.7",
                 "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"
+                "escape-html": "1.0.3",
+                "http-errors": "1.6.3",
+                "mime-types": "2.1.24",
+                "parseurl": "1.3.3"
             },
             "dependencies": {
                 "http-errors": {
@@ -14681,10 +14662,10 @@
                     "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
                     "dev": true,
                     "requires": {
-                        "depd": "~1.1.2",
+                        "depd": "1.1.2",
                         "inherits": "2.0.3",
                         "setprototypeof": "1.1.0",
-                        "statuses": ">= 1.4.0 < 2"
+                        "statuses": "1.5.0"
                     }
                 },
                 "setprototypeof": {
@@ -14700,9 +14681,9 @@
             "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
             "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
             "requires": {
-                "encodeurl": "~1.0.2",
-                "escape-html": "~1.0.3",
-                "parseurl": "~1.3.3",
+                "encodeurl": "1.0.2",
+                "escape-html": "1.0.3",
+                "parseurl": "1.3.3",
                 "send": "0.17.1"
             }
         },
@@ -14716,10 +14697,10 @@
             "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
             "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
             "requires": {
-                "extend-shallow": "^2.0.1",
-                "is-extendable": "^0.1.1",
-                "is-plain-object": "^2.0.3",
-                "split-string": "^3.0.1"
+                "extend-shallow": "2.0.1",
+                "is-extendable": "0.1.1",
+                "is-plain-object": "2.0.4",
+                "split-string": "3.1.0"
             },
             "dependencies": {
                 "extend-shallow": {
@@ -14727,7 +14708,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -14744,11 +14725,11 @@
         },
         "sha.js": {
             "version": "2.4.11",
-            "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+            "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
             "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
             "requires": {
-                "inherits": "^2.0.1",
-                "safe-buffer": "^5.0.1"
+                "inherits": "2.0.3",
+                "safe-buffer": "5.1.2"
             }
         },
         "shallow-clone": {
@@ -14757,7 +14738,7 @@
             "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==",
             "dev": true,
             "requires": {
-                "kind-of": "^6.0.2"
+                "kind-of": "6.0.2"
             }
         },
         "shallow-equal": {
@@ -14770,15 +14751,15 @@
             "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz",
             "integrity": "sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q==",
             "requires": {
-                "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"
+                "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"
             },
             "dependencies": {
                 "chownr": {
@@ -14791,7 +14772,7 @@
                     "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
                     "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
                     "requires": {
-                        "mimic-response": "^2.0.0"
+                        "mimic-response": "2.0.0"
                     }
                 },
                 "fs-minipass": {
@@ -14799,7 +14780,7 @@
                     "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.0.0.tgz",
                     "integrity": "sha512-40Qz+LFXmd9tzYVnnBmZvFfvAADfUA14TXPK1s7IfElJTIZ97rA8w4Kin7Wt5JBrC3ShnnFJO/5vPjPEeJIq9A==",
                     "requires": {
-                        "minipass": "^3.0.0"
+                        "minipass": "3.1.1"
                     }
                 },
                 "mimic-response": {
@@ -14812,7 +14793,7 @@
                     "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz",
                     "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==",
                     "requires": {
-                        "yallist": "^4.0.0"
+                        "yallist": "4.0.0"
                     }
                 },
                 "minizlib": {
@@ -14820,8 +14801,8 @@
                     "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz",
                     "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==",
                     "requires": {
-                        "minipass": "^3.0.0",
-                        "yallist": "^4.0.0"
+                        "minipass": "3.1.1",
+                        "yallist": "4.0.0"
                     }
                 },
                 "semver": {
@@ -14834,9 +14815,9 @@
                     "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
                     "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
                     "requires": {
-                        "decompress-response": "^4.2.0",
-                        "once": "^1.3.1",
-                        "simple-concat": "^1.0.0"
+                        "decompress-response": "4.2.1",
+                        "once": "1.4.0",
+                        "simple-concat": "1.0.0"
                     }
                 },
                 "tar": {
@@ -14844,12 +14825,12 @@
                     "resolved": "https://registry.npmjs.org/tar/-/tar-5.0.5.tgz",
                     "integrity": "sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ==",
                     "requires": {
-                        "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"
+                        "chownr": "1.1.3",
+                        "fs-minipass": "2.0.0",
+                        "minipass": "3.1.1",
+                        "minizlib": "2.1.0",
+                        "mkdirp": "0.5.1",
+                        "yallist": "4.0.0"
                     }
                 },
                 "yallist": {
@@ -14864,7 +14845,7 @@
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
             "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
             "requires": {
-                "shebang-regex": "^1.0.0"
+                "shebang-regex": "1.0.0"
             }
         },
         "shebang-regex": {
@@ -14877,9 +14858,9 @@
             "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
             "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==",
             "requires": {
-                "glob": "^7.0.0",
-                "interpret": "^1.0.0",
-                "rechoir": "^0.6.2"
+                "glob": "7.1.4",
+                "interpret": "1.2.0",
+                "rechoir": "0.6.2"
             }
         },
         "shellwords": {
@@ -14908,9 +14889,9 @@
             "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.3.tgz",
             "integrity": "sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==",
             "requires": {
-                "decompress-response": "^3.3.0",
-                "once": "^1.3.1",
-                "simple-concat": "^1.0.0"
+                "decompress-response": "3.3.0",
+                "once": "1.4.0",
+                "simple-concat": "1.0.0"
             }
         },
         "simple-swizzle": {
@@ -14918,7 +14899,7 @@
             "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
             "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
             "requires": {
-                "is-arrayish": "^0.3.1"
+                "is-arrayish": "0.3.2"
             },
             "dependencies": {
                 "is-arrayish": {
@@ -14944,14 +14925,14 @@
             "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
             "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
             "requires": {
-                "base": "^0.11.1",
-                "debug": "^2.2.0",
-                "define-property": "^0.2.5",
-                "extend-shallow": "^2.0.1",
-                "map-cache": "^0.2.2",
-                "source-map": "^0.5.6",
-                "source-map-resolve": "^0.5.0",
-                "use": "^3.1.0"
+                "base": "0.11.2",
+                "debug": "2.6.9",
+                "define-property": "0.2.5",
+                "extend-shallow": "2.0.1",
+                "map-cache": "0.2.2",
+                "source-map": "0.5.7",
+                "source-map-resolve": "0.5.2",
+                "use": "3.1.1"
             },
             "dependencies": {
                 "define-property": {
@@ -14959,7 +14940,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 },
                 "extend-shallow": {
@@ -14967,7 +14948,7 @@
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
                     "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
-                        "is-extendable": "^0.1.0"
+                        "is-extendable": "0.1.1"
                     }
                 }
             }
@@ -14977,9 +14958,9 @@
             "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
             "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
             "requires": {
-                "define-property": "^1.0.0",
-                "isobject": "^3.0.0",
-                "snapdragon-util": "^3.0.1"
+                "define-property": "1.0.0",
+                "isobject": "3.0.1",
+                "snapdragon-util": "3.0.1"
             },
             "dependencies": {
                 "define-property": {
@@ -14987,7 +14968,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
                     "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
-                        "is-descriptor": "^1.0.0"
+                        "is-descriptor": "1.0.2"
                     }
                 },
                 "is-accessor-descriptor": {
@@ -14995,7 +14976,7 @@
                     "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
                     "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-data-descriptor": {
@@ -15003,7 +14984,7 @@
                     "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
                     "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
                     "requires": {
-                        "kind-of": "^6.0.0"
+                        "kind-of": "6.0.2"
                     }
                 },
                 "is-descriptor": {
@@ -15011,9 +14992,9 @@
                     "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
                     "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
                     "requires": {
-                        "is-accessor-descriptor": "^1.0.0",
-                        "is-data-descriptor": "^1.0.0",
-                        "kind-of": "^6.0.2"
+                        "is-accessor-descriptor": "1.0.0",
+                        "is-data-descriptor": "1.0.0",
+                        "kind-of": "6.0.2"
                     }
                 }
             }
@@ -15023,7 +15004,7 @@
             "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
             "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
             "requires": {
-                "kind-of": "^3.2.0"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -15031,7 +15012,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -15041,12 +15022,12 @@
             "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
             "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
             "requires": {
-                "debug": "~4.1.0",
-                "engine.io": "~3.4.0",
-                "has-binary2": "~1.0.2",
-                "socket.io-adapter": "~1.1.0",
+                "debug": "4.1.1",
+                "engine.io": "3.4.0",
+                "has-binary2": "1.0.3",
+                "socket.io-adapter": "1.1.2",
                 "socket.io-client": "2.3.0",
-                "socket.io-parser": "~3.4.0"
+                "socket.io-parser": "3.4.0"
             },
             "dependencies": {
                 "debug": {
@@ -15054,7 +15035,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15078,15 +15059,15 @@
                 "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",
+                "debug": "4.1.1",
+                "engine.io-client": "3.4.0",
+                "has-binary2": "1.0.3",
                 "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",
+                "socket.io-parser": "3.3.0",
                 "to-array": "0.1.4"
             },
             "dependencies": {
@@ -15100,7 +15081,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "isarray": {
@@ -15119,7 +15100,7 @@
                     "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
                     "requires": {
                         "component-emitter": "1.2.1",
-                        "debug": "~3.1.0",
+                        "debug": "3.1.0",
                         "isarray": "2.0.1"
                     },
                     "dependencies": {
@@ -15146,7 +15127,7 @@
             "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==",
             "requires": {
                 "component-emitter": "1.2.1",
-                "debug": "~4.1.0",
+                "debug": "4.1.1",
                 "isarray": "2.0.1"
             },
             "dependencies": {
@@ -15160,7 +15141,7 @@
                     "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "isarray": {
@@ -15181,8 +15162,8 @@
             "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
             "dev": true,
             "requires": {
-                "faye-websocket": "^0.10.0",
-                "uuid": "^3.0.1"
+                "faye-websocket": "0.10.0",
+                "uuid": "3.3.3"
             }
         },
         "sockjs-client": {
@@ -15191,12 +15172,12 @@
             "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
             "dev": true,
             "requires": {
-                "debug": "^3.2.5",
-                "eventsource": "^1.0.7",
-                "faye-websocket": "~0.11.1",
-                "inherits": "^2.0.3",
-                "json3": "^3.3.2",
-                "url-parse": "^1.4.3"
+                "debug": "3.2.6",
+                "eventsource": "1.0.7",
+                "faye-websocket": "0.11.3",
+                "inherits": "2.0.3",
+                "json3": "3.3.3",
+                "url-parse": "1.4.7"
             },
             "dependencies": {
                 "debug": {
@@ -15205,7 +15186,7 @@
                     "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "faye-websocket": {
@@ -15214,7 +15195,7 @@
                     "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
                     "dev": true,
                     "requires": {
-                        "websocket-driver": ">=0.5.1"
+                        "websocket-driver": "0.7.3"
                     }
                 },
                 "ms": {
@@ -15230,9 +15211,9 @@
             "resolved": "https://registry.npmjs.org/solr-node/-/solr-node-1.2.1.tgz",
             "integrity": "sha512-DN3+FSBgpJEgGTNddzS8tNb+ILSn5MLcsWf15G9rGxi/sROHbpcevdRSVx6s5/nz56c/5AnBTBZWak7IXWX97A==",
             "requires": {
-                "@log4js-node/log4js-api": "^1.0.2",
-                "node-fetch": "^2.3.0",
-                "underscore": "^1.8.3"
+                "@log4js-node/log4js-api": "1.0.2",
+                "node-fetch": "2.6.0",
+                "underscore": "1.9.1"
             },
             "dependencies": {
                 "node-fetch": {
@@ -15258,11 +15239,11 @@
             "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
             "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
             "requires": {
-                "atob": "^2.1.1",
-                "decode-uri-component": "^0.2.0",
-                "resolve-url": "^0.2.1",
-                "source-map-url": "^0.4.0",
-                "urix": "^0.1.0"
+                "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"
             }
         },
         "source-map-support": {
@@ -15271,8 +15252,8 @@
             "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
             "dev": true,
             "requires": {
-                "buffer-from": "^1.0.0",
-                "source-map": "^0.6.0"
+                "buffer-from": "1.1.1",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -15294,7 +15275,7 @@
             "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
             "optional": true,
             "requires": {
-                "memory-pager": "^1.0.2"
+                "memory-pager": "1.5.0"
             }
         },
         "spdx-correct": {
@@ -15302,8 +15283,8 @@
             "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
             "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
             "requires": {
-                "spdx-expression-parse": "^3.0.0",
-                "spdx-license-ids": "^3.0.0"
+                "spdx-expression-parse": "3.0.0",
+                "spdx-license-ids": "3.0.5"
             }
         },
         "spdx-exceptions": {
@@ -15316,8 +15297,8 @@
             "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
             "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
             "requires": {
-                "spdx-exceptions": "^2.1.0",
-                "spdx-license-ids": "^3.0.0"
+                "spdx-exceptions": "2.2.0",
+                "spdx-license-ids": "3.0.5"
             }
         },
         "spdx-license-ids": {
@@ -15331,11 +15312,11 @@
             "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==",
             "dev": true,
             "requires": {
-                "debug": "^4.1.0",
-                "handle-thing": "^2.0.0",
-                "http-deceiver": "^1.2.7",
-                "select-hose": "^2.0.0",
-                "spdy-transport": "^3.0.0"
+                "debug": "4.1.1",
+                "handle-thing": "2.0.0",
+                "http-deceiver": "1.2.7",
+                "select-hose": "2.0.0",
+                "spdy-transport": "3.0.0"
             },
             "dependencies": {
                 "debug": {
@@ -15344,7 +15325,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15361,12 +15342,12 @@
             "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
             "dev": true,
             "requires": {
-                "debug": "^4.1.0",
-                "detect-node": "^2.0.4",
-                "hpack.js": "^2.1.6",
-                "obuf": "^1.1.2",
-                "readable-stream": "^3.0.6",
-                "wbuf": "^1.7.3"
+                "debug": "4.1.1",
+                "detect-node": "2.0.4",
+                "hpack.js": "2.1.6",
+                "obuf": "1.1.2",
+                "readable-stream": "3.4.0",
+                "wbuf": "1.7.3"
             },
             "dependencies": {
                 "debug": {
@@ -15375,7 +15356,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "ms": {
@@ -15390,9 +15371,9 @@
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "dev": true,
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -15412,7 +15393,7 @@
             "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
             "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
             "requires": {
-                "extend-shallow": "^3.0.0"
+                "extend-shallow": "3.0.2"
             }
         },
         "sprintf-js": {
@@ -15425,15 +15406,15 @@
             "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
             "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
             "requires": {
-                "asn1": "~0.2.3",
-                "assert-plus": "^1.0.0",
-                "bcrypt-pbkdf": "^1.0.0",
-                "dashdash": "^1.12.0",
-                "ecc-jsbn": "~0.1.1",
-                "getpass": "^0.1.1",
-                "jsbn": "~0.1.0",
-                "safer-buffer": "^2.0.2",
-                "tweetnacl": "~0.14.0"
+                "asn1": "0.2.4",
+                "assert-plus": "1.0.0",
+                "bcrypt-pbkdf": "1.0.2",
+                "dashdash": "1.14.1",
+                "ecc-jsbn": "0.1.2",
+                "getpass": "0.1.7",
+                "jsbn": "0.1.1",
+                "safer-buffer": "2.1.2",
+                "tweetnacl": "0.14.5"
             },
             "dependencies": {
                 "assert-plus": {
@@ -15449,7 +15430,7 @@
             "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
             "dev": true,
             "requires": {
-                "safe-buffer": "^5.1.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "standard-error": {
@@ -15462,7 +15443,7 @@
             "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz",
             "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=",
             "requires": {
-                "standard-error": ">= 1.1.0 < 2"
+                "standard-error": "1.1.0"
             }
         },
         "static-extend": {
@@ -15470,8 +15451,8 @@
             "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
             "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
             "requires": {
-                "define-property": "^0.2.5",
-                "object-copy": "^0.1.0"
+                "define-property": "0.2.5",
+                "object-copy": "0.1.0"
             },
             "dependencies": {
                 "define-property": {
@@ -15479,7 +15460,7 @@
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
                     "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
-                        "is-descriptor": "^0.1.0"
+                        "is-descriptor": "0.1.6"
                     }
                 }
             }
@@ -15494,7 +15475,7 @@
             "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
             "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
             "requires": {
-                "readable-stream": "^2.0.1"
+                "readable-stream": "2.3.6"
             }
         },
         "stealthy-require": {
@@ -15508,8 +15489,8 @@
             "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
             "dev": true,
             "requires": {
-                "inherits": "~2.0.1",
-                "readable-stream": "^2.0.2"
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6"
             }
         },
         "stream-each": {
@@ -15518,8 +15499,8 @@
             "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
             "dev": true,
             "requires": {
-                "end-of-stream": "^1.1.0",
-                "stream-shift": "^1.0.0"
+                "end-of-stream": "1.4.1",
+                "stream-shift": "1.0.0"
             }
         },
         "stream-http": {
@@ -15528,11 +15509,11 @@
             "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
             "dev": true,
             "requires": {
-                "builtin-status-codes": "^3.0.0",
-                "inherits": "^2.0.1",
-                "readable-stream": "^2.3.6",
-                "to-arraybuffer": "^1.0.0",
-                "xtend": "^4.0.0"
+                "builtin-status-codes": "3.0.0",
+                "inherits": "2.0.3",
+                "readable-stream": "2.3.6",
+                "to-arraybuffer": "1.0.1",
+                "xtend": "4.0.2"
             }
         },
         "stream-parser": {
@@ -15540,7 +15521,7 @@
             "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
             "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
             "requires": {
-                "debug": "2"
+                "debug": "2.6.9"
             }
         },
         "stream-shift": {
@@ -15559,9 +15540,9 @@
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
             "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
             "requires": {
-                "code-point-at": "^1.0.0",
-                "is-fullwidth-code-point": "^1.0.0",
-                "strip-ansi": "^3.0.0"
+                "code-point-at": "1.1.0",
+                "is-fullwidth-code-point": "1.0.0",
+                "strip-ansi": "3.0.1"
             }
         },
         "string.prototype.trimleft": {
@@ -15569,8 +15550,8 @@
             "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz",
             "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==",
             "requires": {
-                "define-properties": "^1.1.3",
-                "function-bind": "^1.1.1"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1"
             }
         },
         "string.prototype.trimright": {
@@ -15578,16 +15559,16 @@
             "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz",
             "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==",
             "requires": {
-                "define-properties": "^1.1.3",
-                "function-bind": "^1.1.1"
+                "define-properties": "1.1.3",
+                "function-bind": "1.1.1"
             }
         },
         "string_decoder": {
             "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
             "requires": {
-                "safe-buffer": "~5.1.0"
+                "safe-buffer": "5.1.2"
             }
         },
         "stringify-parameters": {
@@ -15604,10 +15585,10 @@
                     "resolved": "https://registry.npmjs.org/magicli/-/magicli-0.0.5.tgz",
                     "integrity": "sha1-zufQ+7THBRiqyxHsPrfiX/SaSSE=",
                     "requires": {
-                        "commander": "^2.9.0",
-                        "get-stdin": "^5.0.1",
-                        "inspect-function": "^0.2.1",
-                        "pipe-functions": "^1.2.0"
+                        "commander": "2.20.0",
+                        "get-stdin": "5.0.1",
+                        "inspect-function": "0.2.2",
+                        "pipe-functions": "1.3.0"
                     }
                 }
             }
@@ -15617,7 +15598,7 @@
             "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
             "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
             "requires": {
-                "ansi-regex": "^2.0.0"
+                "ansi-regex": "2.1.1"
             }
         },
         "strip-bom": {
@@ -15625,12 +15606,12 @@
             "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
             "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
             "requires": {
-                "is-utf8": "^0.2.0"
+                "is-utf8": "0.2.1"
             }
         },
         "strip-eof": {
             "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
             "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
         },
         "strip-indent": {
@@ -15638,7 +15619,7 @@
             "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
             "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
             "requires": {
-                "get-stdin": "^4.0.1"
+                "get-stdin": "4.0.1"
             },
             "dependencies": {
                 "get-stdin": {
@@ -15659,8 +15640,8 @@
             "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.1.0",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "schema-utils": {
@@ -15669,9 +15650,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -15692,11 +15673,11 @@
             "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
             "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
             "requires": {
-                "array-back": "^2.0.0",
-                "deep-extend": "~0.6.0",
-                "lodash.padend": "^4.6.1",
-                "typical": "^2.6.1",
-                "wordwrapjs": "^3.0.0"
+                "array-back": "2.0.0",
+                "deep-extend": "0.6.0",
+                "lodash.padend": "4.6.1",
+                "typical": "2.6.1",
+                "wordwrapjs": "3.0.0"
             }
         },
         "tapable": {
@@ -15710,13 +15691,13 @@
             "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
             "integrity": "sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==",
             "requires": {
-                "chownr": "^1.1.1",
-                "fs-minipass": "^1.2.5",
-                "minipass": "^2.3.5",
-                "minizlib": "^1.2.1",
-                "mkdirp": "^0.5.0",
-                "safe-buffer": "^5.1.2",
-                "yallist": "^3.0.3"
+                "chownr": "1.1.2",
+                "fs-minipass": "1.2.6",
+                "minipass": "2.3.5",
+                "minizlib": "1.2.1",
+                "mkdirp": "0.5.1",
+                "safe-buffer": "5.1.2",
+                "yallist": "3.0.3"
             }
         },
         "tar-fs": {
@@ -15724,10 +15705,10 @@
             "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
             "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
             "requires": {
-                "chownr": "^1.1.1",
-                "mkdirp": "^0.5.1",
-                "pump": "^3.0.0",
-                "tar-stream": "^2.0.0"
+                "chownr": "1.1.2",
+                "mkdirp": "0.5.1",
+                "pump": "3.0.0",
+                "tar-stream": "2.1.0"
             },
             "dependencies": {
                 "pump": {
@@ -15735,8 +15716,8 @@
                     "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 }
             }
@@ -15746,11 +15727,11 @@
             "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.0.tgz",
             "integrity": "sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==",
             "requires": {
-                "bl": "^3.0.0",
-                "end-of-stream": "^1.4.1",
-                "fs-constants": "^1.0.0",
-                "inherits": "^2.0.3",
-                "readable-stream": "^3.1.1"
+                "bl": "3.0.0",
+                "end-of-stream": "1.4.1",
+                "fs-constants": "1.0.0",
+                "inherits": "2.0.3",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -15758,9 +15739,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
@@ -15770,7 +15751,7 @@
             "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
             "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
             "requires": {
-                "execa": "^0.7.0"
+                "execa": "0.7.0"
             }
         },
         "terser": {
@@ -15779,9 +15760,9 @@
             "integrity": "sha512-lH9zLIbX8PRBEFCTvfHGCy0s9HEKnNso1Dx9swSopF3VUnFLB8DpQ61tHxoofovNC/sG0spajJM3EIIRSTByiQ==",
             "dev": true,
             "requires": {
-                "commander": "^2.20.0",
-                "source-map": "~0.6.1",
-                "source-map-support": "~0.5.12"
+                "commander": "2.20.0",
+                "source-map": "0.6.1",
+                "source-map-support": "0.5.12"
             },
             "dependencies": {
                 "source-map": {
@@ -15798,15 +15779,15 @@
             "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==",
             "dev": true,
             "requires": {
-                "cacache": "^12.0.2",
-                "find-cache-dir": "^2.1.0",
-                "is-wsl": "^1.1.0",
-                "schema-utils": "^1.0.0",
-                "serialize-javascript": "^2.1.2",
-                "source-map": "^0.6.1",
-                "terser": "^4.1.2",
-                "webpack-sources": "^1.4.0",
-                "worker-farm": "^1.7.0"
+                "cacache": "12.0.3",
+                "find-cache-dir": "2.1.0",
+                "is-wsl": "1.1.0",
+                "schema-utils": "1.0.0",
+                "serialize-javascript": "2.1.2",
+                "source-map": "0.6.1",
+                "terser": "4.5.1",
+                "webpack-sources": "1.4.3",
+                "worker-farm": "1.7.0"
             },
             "dependencies": {
                 "cacache": {
@@ -15815,21 +15796,21 @@
                     "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
                     "dev": true,
                     "requires": {
-                        "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"
+                        "bluebird": "3.7.2",
+                        "chownr": "1.1.2",
+                        "figgy-pudding": "3.5.1",
+                        "glob": "7.1.4",
+                        "graceful-fs": "4.2.0",
+                        "infer-owner": "1.0.4",
+                        "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.7.1",
+                        "ssri": "6.0.1",
+                        "unique-filename": "1.1.1",
+                        "y18n": "4.0.0"
                     }
                 },
                 "find-cache-dir": {
@@ -15838,9 +15819,9 @@
                     "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
                     "dev": true,
                     "requires": {
-                        "commondir": "^1.0.1",
-                        "make-dir": "^2.0.0",
-                        "pkg-dir": "^3.0.0"
+                        "commondir": "1.0.1",
+                        "make-dir": "2.1.0",
+                        "pkg-dir": "3.0.0"
                     }
                 },
                 "find-up": {
@@ -15849,7 +15830,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "locate-path": {
@@ -15858,8 +15839,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "lru-cache": {
@@ -15868,7 +15849,7 @@
                     "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
                     "dev": true,
                     "requires": {
-                        "yallist": "^3.0.2"
+                        "yallist": "3.0.3"
                     }
                 },
                 "make-dir": {
@@ -15877,8 +15858,8 @@
                     "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
                     "dev": true,
                     "requires": {
-                        "pify": "^4.0.1",
-                        "semver": "^5.6.0"
+                        "pify": "4.0.1",
+                        "semver": "5.7.0"
                     }
                 },
                 "mississippi": {
@@ -15887,16 +15868,16 @@
                     "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
                     "dev": true,
                     "requires": {
-                        "concat-stream": "^1.5.0",
-                        "duplexify": "^3.4.2",
-                        "end-of-stream": "^1.1.0",
-                        "flush-write-stream": "^1.0.0",
-                        "from2": "^2.1.0",
-                        "parallel-transform": "^1.1.0",
-                        "pump": "^3.0.0",
-                        "pumpify": "^1.3.3",
-                        "stream-each": "^1.1.0",
-                        "through2": "^2.0.0"
+                        "concat-stream": "1.6.2",
+                        "duplexify": "3.7.1",
+                        "end-of-stream": "1.4.1",
+                        "flush-write-stream": "1.1.1",
+                        "from2": "2.3.0",
+                        "parallel-transform": "1.1.0",
+                        "pump": "3.0.0",
+                        "pumpify": "1.5.1",
+                        "stream-each": "1.2.3",
+                        "through2": "2.0.5"
                     }
                 },
                 "p-locate": {
@@ -15905,7 +15886,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "pify": {
@@ -15920,7 +15901,7 @@
                     "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
                     "dev": true,
                     "requires": {
-                        "find-up": "^3.0.0"
+                        "find-up": "3.0.0"
                     }
                 },
                 "pump": {
@@ -15929,8 +15910,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "rimraf": {
@@ -15939,7 +15920,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 },
                 "schema-utils": {
@@ -15948,9 +15929,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 },
                 "serialize-javascript": {
@@ -15971,7 +15952,7 @@
                     "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
                     "dev": true,
                     "requires": {
-                        "figgy-pudding": "^3.5.1"
+                        "figgy-pudding": "3.5.1"
                     }
                 },
                 "y18n": {
@@ -15987,8 +15968,8 @@
             "resolved": "https://registry.npmjs.org/threads/-/threads-0.8.1.tgz",
             "integrity": "sha1-40ARW1lHMW0vfuMSPEwsW/nHbXI=",
             "requires": {
-                "eventemitter3": "^2.0.2",
-                "native-promise-only": "^0.8.1"
+                "eventemitter3": "2.0.3",
+                "native-promise-only": "0.8.1"
             }
         },
         "through": {
@@ -16002,8 +15983,8 @@
             "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
             "dev": true,
             "requires": {
-                "readable-stream": "~2.3.6",
-                "xtend": "~4.0.1"
+                "readable-stream": "2.3.6",
+                "xtend": "4.0.2"
             }
         },
         "thunky": {
@@ -16023,7 +16004,7 @@
             "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==",
             "dev": true,
             "requires": {
-                "setimmediate": "^1.0.4"
+                "setimmediate": "1.0.5"
             }
         },
         "tinycolor2": {
@@ -16052,7 +16033,7 @@
             "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
             "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
             "requires": {
-                "kind-of": "^3.0.2"
+                "kind-of": "3.2.2"
             },
             "dependencies": {
                 "kind-of": {
@@ -16060,7 +16041,7 @@
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
                     "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
-                        "is-buffer": "^1.1.5"
+                        "is-buffer": "1.1.6"
                     }
                 }
             }
@@ -16070,10 +16051,10 @@
             "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
             "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
             "requires": {
-                "define-property": "^2.0.2",
-                "extend-shallow": "^3.0.2",
-                "regex-not": "^1.0.2",
-                "safe-regex": "^1.1.0"
+                "define-property": "2.0.2",
+                "extend-shallow": "3.0.2",
+                "regex-not": "1.0.2",
+                "safe-regex": "1.1.0"
             }
         },
         "to-regex-range": {
@@ -16081,8 +16062,8 @@
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
             "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
             "requires": {
-                "is-number": "^3.0.0",
-                "repeat-string": "^1.6.1"
+                "is-number": "3.0.0",
+                "repeat-string": "1.6.1"
             }
         },
         "toidentifier": {
@@ -16100,7 +16081,7 @@
             "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
             "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
             "requires": {
-                "nopt": "~1.0.10"
+                "nopt": "1.0.10"
             },
             "dependencies": {
                 "nopt": {
@@ -16108,7 +16089,7 @@
                     "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
                     "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
                     "requires": {
-                        "abbrev": "1"
+                        "abbrev": "1.1.1"
                     }
                 }
             }
@@ -16118,8 +16099,8 @@
             "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
             "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
             "requires": {
-                "psl": "^1.1.24",
-                "punycode": "^1.4.1"
+                "psl": "1.2.0",
+                "punycode": "1.4.1"
             },
             "dependencies": {
                 "punycode": {
@@ -16135,7 +16116,7 @@
             "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
             "dev": true,
             "requires": {
-                "punycode": "^2.1.0"
+                "punycode": "2.1.1"
             }
         },
         "traverse-chain": {
@@ -16159,7 +16140,7 @@
             "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
             "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
             "requires": {
-                "glob": "^7.1.2"
+                "glob": "7.1.4"
             }
         },
         "ts-loader": {
@@ -16168,11 +16149,11 @@
             "integrity": "sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==",
             "dev": true,
             "requires": {
-                "chalk": "^2.3.0",
-                "enhanced-resolve": "^4.0.0",
-                "loader-utils": "^1.0.2",
-                "micromatch": "^3.1.4",
-                "semver": "^5.0.1"
+                "chalk": "2.4.2",
+                "enhanced-resolve": "4.1.0",
+                "loader-utils": "1.2.3",
+                "micromatch": "3.1.10",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16181,7 +16162,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16190,9 +16171,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -16201,7 +16182,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16212,14 +16193,14 @@
             "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==",
             "dev": true,
             "requires": {
-                "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"
+                "arrify": "1.0.1",
+                "buffer-from": "1.1.1",
+                "diff": "3.5.0",
+                "make-error": "1.3.5",
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "source-map-support": "0.5.12",
+                "yn": "2.0.0"
             },
             "dependencies": {
                 "diff": {
@@ -16242,18 +16223,18 @@
             "integrity": "sha512-M5ZwvB6FU3jtc70i5lFth86/6Qj5XR5nMMBwVxZF4cZhpO7XcbWw6tbNiJo22Zx0KfjEj9py5DANhwLOkPPufw==",
             "dev": true,
             "requires": {
-                "dateformat": "~1.0.4-1.2.3",
-                "dynamic-dedupe": "^0.3.0",
-                "filewatcher": "~3.0.0",
-                "minimist": "^1.1.3",
-                "mkdirp": "^0.5.1",
-                "node-notifier": "^5.4.0",
-                "resolve": "^1.0.0",
-                "rimraf": "^2.6.1",
-                "source-map-support": "^0.5.12",
-                "tree-kill": "^1.2.1",
-                "ts-node": "*",
-                "tsconfig": "^7.0.0"
+                "dateformat": "1.0.12",
+                "dynamic-dedupe": "0.3.0",
+                "filewatcher": "3.0.1",
+                "minimist": "1.2.0",
+                "mkdirp": "0.5.1",
+                "node-notifier": "5.4.3",
+                "resolve": "1.11.1",
+                "rimraf": "2.7.1",
+                "source-map-support": "0.5.12",
+                "tree-kill": "1.2.2",
+                "ts-node": "7.0.1",
+                "tsconfig": "7.0.0"
             },
             "dependencies": {
                 "minimist": {
@@ -16268,7 +16249,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -16279,10 +16260,10 @@
             "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
             "dev": true,
             "requires": {
-                "@types/strip-bom": "^3.0.0",
+                "@types/strip-bom": "3.0.0",
                 "@types/strip-json-comments": "0.0.30",
-                "strip-bom": "^3.0.0",
-                "strip-json-comments": "^2.0.0"
+                "strip-bom": "3.0.0",
+                "strip-json-comments": "2.0.1"
             },
             "dependencies": {
                 "strip-bom": {
@@ -16305,19 +16286,19 @@
             "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
             "dev": true,
             "requires": {
-                "@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"
+                "@babel/code-frame": "7.5.5",
+                "builtin-modules": "1.1.1",
+                "chalk": "2.4.2",
+                "commander": "2.20.0",
+                "diff": "4.0.1",
+                "glob": "7.1.4",
+                "js-yaml": "3.13.1",
+                "minimatch": "3.0.4",
+                "mkdirp": "0.5.1",
+                "resolve": "1.11.1",
+                "semver": "5.7.0",
+                "tslib": "1.10.0",
+                "tsutils": "2.29.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16326,7 +16307,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16335,9 +16316,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "diff": {
@@ -16352,7 +16333,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16363,11 +16344,11 @@
             "integrity": "sha512-jBHNNppXut6SgZ7CsTBh+6oMwVum9n8azbmcYSeMlsABhWWoHwjq631vIFXef3VSd75cCdX3rc6kstsB7rSVVw==",
             "dev": true,
             "requires": {
-                "loader-utils": "^1.0.2",
-                "mkdirp": "^0.5.1",
-                "object-assign": "^4.1.1",
-                "rimraf": "^2.4.4",
-                "semver": "^5.3.0"
+                "loader-utils": "1.2.3",
+                "mkdirp": "0.5.1",
+                "object-assign": "4.1.1",
+                "rimraf": "2.7.1",
+                "semver": "5.7.0"
             },
             "dependencies": {
                 "rimraf": {
@@ -16376,7 +16357,7 @@
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "dev": true,
                     "requires": {
-                        "glob": "^7.1.3"
+                        "glob": "7.1.4"
                     }
                 }
             }
@@ -16387,12 +16368,12 @@
             "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
             "dev": true,
             "requires": {
-                "tslib": "^1.8.1"
+                "tslib": "1.10.0"
             }
         },
         "tty-browserify": {
             "version": "0.0.0",
-            "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+            "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
             "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
             "dev": true
         },
@@ -16401,7 +16382,7 @@
             "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
             "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
             "requires": {
-                "safe-buffer": "^5.0.1"
+                "safe-buffer": "5.1.2"
             }
         },
         "tweetnacl": {
@@ -16421,7 +16402,7 @@
             "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
             "dev": true,
             "requires": {
-                "prelude-ls": "~1.1.2"
+                "prelude-ls": "1.1.2"
             }
         },
         "type-detect": {
@@ -16435,7 +16416,7 @@
             "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
             "requires": {
                 "media-typer": "0.3.0",
-                "mime-types": "~2.1.24"
+                "mime-types": "2.1.24"
             }
         },
         "typedarray": {
@@ -16469,9 +16450,9 @@
             "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
             "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
             "requires": {
-                "source-map": "~0.5.1",
-                "uglify-to-browserify": "~1.0.0",
-                "yargs": "~3.10.0"
+                "source-map": "0.5.7",
+                "uglify-to-browserify": "1.0.2",
+                "yargs": "3.10.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -16484,8 +16465,8 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
                     "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
                     "requires": {
-                        "center-align": "^0.1.1",
-                        "right-align": "^0.1.1",
+                        "center-align": "0.1.3",
+                        "right-align": "0.1.3",
                         "wordwrap": "0.0.2"
                     }
                 },
@@ -16494,9 +16475,9 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
                     "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
                     "requires": {
-                        "camelcase": "^1.0.2",
-                        "cliui": "^2.1.0",
-                        "decamelize": "^1.0.0",
+                        "camelcase": "1.2.1",
+                        "cliui": "2.1.0",
+                        "decamelize": "1.2.0",
                         "window-size": "0.1.0"
                     }
                 }
@@ -16513,7 +16494,7 @@
             "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
             "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
             "requires": {
-                "random-bytes": "~1.0.0"
+                "random-bytes": "1.0.0"
             }
         },
         "uid2": {
@@ -16526,7 +16507,7 @@
             "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-5.1.0.tgz",
             "integrity": "sha512-5FXYaFANKaafg4IVZXUNtGyzsnYEvqlr9wQ3WpZxFpEUxl29A3H6Q4G1Dnnorvq9TGOGATBApWR4YpLAh+F5hw==",
             "requires": {
-                "invariant": "^2.2.4"
+                "invariant": "2.2.4"
             }
         },
         "undefsafe": {
@@ -16534,7 +16515,7 @@
             "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
             "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
             "requires": {
-                "debug": "^2.2.0"
+                "debug": "2.6.9"
             }
         },
         "underscore": {
@@ -16547,10 +16528,10 @@
             "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
             "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
             "requires": {
-                "arr-union": "^3.1.0",
-                "get-value": "^2.0.6",
-                "is-extendable": "^0.1.1",
-                "set-value": "^2.0.1"
+                "arr-union": "3.1.0",
+                "get-value": "2.0.6",
+                "is-extendable": "0.1.1",
+                "set-value": "2.0.1"
             }
         },
         "uniq": {
@@ -16565,7 +16546,7 @@
             "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
             "dev": true,
             "requires": {
-                "unique-slug": "^2.0.0"
+                "unique-slug": "2.0.2"
             }
         },
         "unique-slug": {
@@ -16574,7 +16555,7 @@
             "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
             "dev": true,
             "requires": {
-                "imurmurhash": "^0.1.4"
+                "imurmurhash": "0.1.4"
             }
         },
         "unique-string": {
@@ -16582,7 +16563,7 @@
             "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
             "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
             "requires": {
-                "crypto-random-string": "^1.0.0"
+                "crypto-random-string": "1.0.0"
             }
         },
         "unpack-string": {
@@ -16600,8 +16581,8 @@
             "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
             "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
             "requires": {
-                "has-value": "^0.3.1",
-                "isobject": "^3.0.0"
+                "has-value": "0.3.1",
+                "isobject": "3.0.1"
             },
             "dependencies": {
                 "has-value": {
@@ -16609,9 +16590,9 @@
                     "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
                     "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
                     "requires": {
-                        "get-value": "^2.0.3",
-                        "has-values": "^0.1.4",
-                        "isobject": "^2.0.0"
+                        "get-value": "2.0.6",
+                        "has-values": "0.1.4",
+                        "isobject": "2.1.0"
                     },
                     "dependencies": {
                         "isobject": {
@@ -16646,16 +16627,16 @@
             "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
             "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
             "requires": {
-                "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"
+                "boxen": "1.3.0",
+                "chalk": "2.4.2",
+                "configstore": "3.1.2",
+                "import-lazy": "2.1.0",
+                "is-ci": "1.2.1",
+                "is-installed-globally": "0.1.0",
+                "is-npm": "1.0.0",
+                "latest-version": "3.1.0",
+                "semver-diff": "2.1.0",
+                "xdg-basedir": "3.0.0"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -16663,7 +16644,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -16671,9 +16652,9 @@
                     "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -16681,7 +16662,7 @@
                     "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -16691,7 +16672,7 @@
             "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
             "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
             "requires": {
-                "punycode": "^2.1.0"
+                "punycode": "2.1.1"
             }
         },
         "urix": {
@@ -16722,9 +16703,9 @@
             "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-1.1.2.tgz",
             "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==",
             "requires": {
-                "loader-utils": "^1.1.0",
-                "mime": "^2.0.3",
-                "schema-utils": "^1.0.0"
+                "loader-utils": "1.2.3",
+                "mime": "2.4.4",
+                "schema-utils": "1.0.0"
             },
             "dependencies": {
                 "mime": {
@@ -16737,9 +16718,9 @@
                     "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -16750,8 +16731,8 @@
             "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
             "dev": true,
             "requires": {
-                "querystringify": "^2.1.1",
-                "requires-port": "^1.0.0"
+                "querystringify": "2.1.1",
+                "requires-port": "1.0.0"
             }
         },
         "url-parse-lax": {
@@ -16759,7 +16740,7 @@
             "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
             "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
             "requires": {
-                "prepend-http": "^1.0.1"
+                "prepend-http": "1.0.4"
             }
         },
         "url-template": {
@@ -16807,8 +16788,8 @@
             "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
             "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
             "requires": {
-                "spdx-correct": "^3.0.0",
-                "spdx-expression-parse": "^3.0.0"
+                "spdx-correct": "3.1.0",
+                "spdx-expression-parse": "3.0.0"
             }
         },
         "validator": {
@@ -16826,9 +16807,9 @@
             "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
             "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
             "requires": {
-                "assert-plus": "^1.0.0",
+                "assert-plus": "1.0.0",
                 "core-util-is": "1.0.2",
-                "extsprintf": "^1.2.0"
+                "extsprintf": "1.3.0"
             },
             "dependencies": {
                 "assert-plus": {
@@ -16855,7 +16836,7 @@
             "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
             "dev": true,
             "requires": {
-                "browser-process-hrtime": "^0.1.2"
+                "browser-process-hrtime": "0.1.3"
             }
         },
         "w3c-keyname": {
@@ -16869,9 +16850,9 @@
             "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
             "dev": true,
             "requires": {
-                "domexception": "^1.0.1",
-                "webidl-conversions": "^4.0.2",
-                "xml-name-validator": "^3.0.0"
+                "domexception": "1.0.1",
+                "webidl-conversions": "4.0.2",
+                "xml-name-validator": "3.0.0"
             }
         },
         "warning": {
@@ -16879,7 +16860,7 @@
             "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
             "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
             "requires": {
-                "loose-envify": "^1.0.0"
+                "loose-envify": "1.4.0"
             }
         },
         "watchpack": {
@@ -16888,9 +16869,9 @@
             "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
             "dev": true,
             "requires": {
-                "chokidar": "^2.0.2",
-                "graceful-fs": "^4.1.2",
-                "neo-async": "^2.5.0"
+                "chokidar": "2.1.8",
+                "graceful-fs": "4.2.0",
+                "neo-async": "2.6.1"
             }
         },
         "wbuf": {
@@ -16899,7 +16880,7 @@
             "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
             "dev": true,
             "requires": {
-                "minimalistic-assert": "^1.0.0"
+                "minimalistic-assert": "1.0.1"
             }
         },
         "webidl-conversions": {
@@ -16918,25 +16899,25 @@
                 "@webassemblyjs/helper-module-context": "1.8.5",
                 "@webassemblyjs/wasm-edit": "1.8.5",
                 "@webassemblyjs/wasm-parser": "1.8.5",
-                "acorn": "^6.2.1",
-                "ajv": "^6.10.2",
-                "ajv-keywords": "^3.4.1",
-                "chrome-trace-event": "^1.0.2",
-                "enhanced-resolve": "^4.1.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.1",
-                "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.6.0",
-                "webpack-sources": "^1.4.1"
+                "acorn": "6.4.0",
+                "ajv": "6.10.2",
+                "ajv-keywords": "3.4.1",
+                "chrome-trace-event": "1.0.2",
+                "enhanced-resolve": "4.1.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.1",
+                "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.6.0",
+                "webpack-sources": "1.4.3"
             },
             "dependencies": {
                 "acorn": {
@@ -16951,9 +16932,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 }
             }
@@ -16989,7 +16970,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "camelcase": {
@@ -17004,9 +16985,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     },
                     "dependencies": {
                         "supports-color": {
@@ -17015,7 +16996,7 @@
                             "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                             "dev": true,
                             "requires": {
-                                "has-flag": "^3.0.0"
+                                "has-flag": "3.0.0"
                             }
                         }
                     }
@@ -17026,9 +17007,9 @@
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "dev": true,
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "execa": {
@@ -17037,13 +17018,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "find-up": {
@@ -17052,7 +17033,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-caller-file": {
@@ -17067,7 +17048,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -17088,7 +17069,7 @@
                     "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
                     "dev": true,
                     "requires": {
-                        "invert-kv": "^2.0.0"
+                        "invert-kv": "2.0.0"
                     }
                 },
                 "locate-path": {
@@ -17097,8 +17078,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "os-locale": {
@@ -17107,9 +17088,9 @@
                     "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
                     "dev": true,
                     "requires": {
-                        "execa": "^1.0.0",
-                        "lcid": "^2.0.0",
-                        "mem": "^4.0.0"
+                        "execa": "1.0.0",
+                        "lcid": "2.0.0",
+                        "mem": "4.3.0"
                     }
                 },
                 "p-locate": {
@@ -17118,7 +17099,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "pump": {
@@ -17127,8 +17108,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "require-main-filename": {
@@ -17143,9 +17124,9 @@
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "dev": true,
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -17154,7 +17135,7 @@
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "dev": true,
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "supports-color": {
@@ -17163,7 +17144,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "which-module": {
@@ -17178,9 +17159,9 @@
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -17195,17 +17176,17 @@
                     "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==",
                     "dev": true,
                     "requires": {
-                        "cliui": "^5.0.0",
-                        "find-up": "^3.0.0",
-                        "get-caller-file": "^2.0.1",
-                        "os-locale": "^3.1.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^2.0.0",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^3.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^4.0.0",
-                        "yargs-parser": "^13.1.0"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "os-locale": "3.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -17214,8 +17195,8 @@
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "dev": true,
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -17226,11 +17207,11 @@
             "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
             "dev": true,
             "requires": {
-                "memory-fs": "^0.4.1",
-                "mime": "^2.4.4",
-                "mkdirp": "^0.5.1",
-                "range-parser": "^1.2.1",
-                "webpack-log": "^2.0.0"
+                "memory-fs": "0.4.1",
+                "mime": "2.4.4",
+                "mkdirp": "0.5.1",
+                "range-parser": "1.2.1",
+                "webpack-log": "2.0.0"
             },
             "dependencies": {
                 "mime": {
@@ -17245,8 +17226,8 @@
                     "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
                     "dev": true,
                     "requires": {
-                        "ansi-colors": "^3.0.0",
-                        "uuid": "^3.3.2"
+                        "ansi-colors": "3.2.4",
+                        "uuid": "3.3.3"
                     }
                 }
             }
@@ -17258,37 +17239,37 @@
             "dev": true,
             "requires": {
                 "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.2.1",
+                "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.2.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.6",
-                "opn": "^5.5.0",
-                "p-retry": "^3.0.1",
-                "portfinder": "^1.0.25",
-                "schema-utils": "^1.0.0",
-                "selfsigned": "^1.10.7",
-                "semver": "^6.3.0",
-                "serve-index": "^1.9.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.6",
+                "opn": "5.5.0",
+                "p-retry": "3.0.1",
+                "portfinder": "1.0.25",
+                "schema-utils": "1.0.0",
+                "selfsigned": "1.10.7",
+                "semver": "6.3.0",
+                "serve-index": "1.9.1",
                 "sockjs": "0.3.19",
                 "sockjs-client": "1.4.0",
-                "spdy": "^4.0.1",
-                "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",
+                "spdy": "4.0.1",
+                "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": "12.0.5"
             },
             "dependencies": {
@@ -17310,9 +17291,9 @@
                     "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
                     "dev": true,
                     "requires": {
-                        "string-width": "^2.1.1",
-                        "strip-ansi": "^4.0.0",
-                        "wrap-ansi": "^2.0.0"
+                        "string-width": "2.1.1",
+                        "strip-ansi": "4.0.0",
+                        "wrap-ansi": "2.1.0"
                     },
                     "dependencies": {
                         "strip-ansi": {
@@ -17321,7 +17302,7 @@
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "dev": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -17332,7 +17313,7 @@
                     "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
                     "dev": true,
                     "requires": {
-                        "ms": "^2.1.1"
+                        "ms": "2.1.2"
                     }
                 },
                 "execa": {
@@ -17341,13 +17322,13 @@
                     "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
                     "dev": true,
                     "requires": {
-                        "cross-spawn": "^6.0.0",
-                        "get-stream": "^4.0.0",
-                        "is-stream": "^1.1.0",
-                        "npm-run-path": "^2.0.0",
-                        "p-finally": "^1.0.0",
-                        "signal-exit": "^3.0.0",
-                        "strip-eof": "^1.0.0"
+                        "cross-spawn": "6.0.5",
+                        "get-stream": "4.1.0",
+                        "is-stream": "1.1.0",
+                        "npm-run-path": "2.0.2",
+                        "p-finally": "1.0.0",
+                        "signal-exit": "3.0.2",
+                        "strip-eof": "1.0.0"
                     }
                 },
                 "find-up": {
@@ -17356,7 +17337,7 @@
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "dev": true,
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-stream": {
@@ -17365,7 +17346,7 @@
                     "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
                     "dev": true,
                     "requires": {
-                        "pump": "^3.0.0"
+                        "pump": "3.0.0"
                     }
                 },
                 "invert-kv": {
@@ -17386,7 +17367,7 @@
                     "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
                     "dev": true,
                     "requires": {
-                        "invert-kv": "^2.0.0"
+                        "invert-kv": "2.0.0"
                     }
                 },
                 "locate-path": {
@@ -17395,8 +17376,8 @@
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "dev": true,
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "loglevel": {
@@ -17417,9 +17398,9 @@
                     "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
                     "dev": true,
                     "requires": {
-                        "execa": "^1.0.0",
-                        "lcid": "^2.0.0",
-                        "mem": "^4.0.0"
+                        "execa": "1.0.0",
+                        "lcid": "2.0.0",
+                        "mem": "4.3.0"
                     }
                 },
                 "p-locate": {
@@ -17428,7 +17409,7 @@
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "dev": true,
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "pump": {
@@ -17437,8 +17418,8 @@
                     "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
                     "dev": true,
                     "requires": {
-                        "end-of-stream": "^1.1.0",
-                        "once": "^1.3.1"
+                        "end-of-stream": "1.4.1",
+                        "once": "1.4.0"
                     }
                 },
                 "schema-utils": {
@@ -17447,9 +17428,9 @@
                     "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
                     "dev": true,
                     "requires": {
-                        "ajv": "^6.1.0",
-                        "ajv-errors": "^1.0.0",
-                        "ajv-keywords": "^3.1.0"
+                        "ajv": "6.10.2",
+                        "ajv-errors": "1.0.1",
+                        "ajv-keywords": "3.4.1"
                     }
                 },
                 "semver": {
@@ -17464,8 +17445,8 @@
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "dev": true,
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     },
                     "dependencies": {
                         "strip-ansi": {
@@ -17474,7 +17455,7 @@
                             "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                             "dev": true,
                             "requires": {
-                                "ansi-regex": "^3.0.0"
+                                "ansi-regex": "3.0.0"
                             }
                         }
                     }
@@ -17485,7 +17466,7 @@
                     "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 },
                 "webpack-log": {
@@ -17494,8 +17475,8 @@
                     "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
                     "dev": true,
                     "requires": {
-                        "ansi-colors": "^3.0.0",
-                        "uuid": "^3.3.2"
+                        "ansi-colors": "3.2.4",
+                        "uuid": "3.3.3"
                     }
                 },
                 "which-module": {
@@ -17510,7 +17491,7 @@
                     "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
                     "dev": true,
                     "requires": {
-                        "async-limiter": "~1.0.0"
+                        "async-limiter": "1.0.1"
                     }
                 },
                 "yargs": {
@@ -17519,18 +17500,18 @@
                     "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
                     "dev": true,
                     "requires": {
-                        "cliui": "^4.0.0",
-                        "decamelize": "^1.2.0",
-                        "find-up": "^3.0.0",
-                        "get-caller-file": "^1.0.1",
-                        "os-locale": "^3.0.0",
-                        "require-directory": "^2.1.1",
-                        "require-main-filename": "^1.0.1",
-                        "set-blocking": "^2.0.0",
-                        "string-width": "^2.0.0",
-                        "which-module": "^2.0.0",
-                        "y18n": "^3.2.1 || ^4.0.0",
-                        "yargs-parser": "^11.1.1"
+                        "cliui": "4.1.0",
+                        "decamelize": "1.2.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "1.0.3",
+                        "os-locale": "3.1.0",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "1.0.1",
+                        "set-blocking": "2.0.0",
+                        "string-width": "2.1.1",
+                        "which-module": "2.0.0",
+                        "y18n": "3.2.1",
+                        "yargs-parser": "11.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -17539,8 +17520,8 @@
                     "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
                     "dev": true,
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -17552,9 +17533,9 @@
             "dev": true,
             "requires": {
                 "ansi-html": "0.0.7",
-                "html-entities": "^1.2.0",
-                "querystring": "^0.2.0",
-                "strip-ansi": "^3.0.0"
+                "html-entities": "1.2.1",
+                "querystring": "0.2.0",
+                "strip-ansi": "3.0.1"
             }
         },
         "webpack-log": {
@@ -17563,10 +17544,10 @@
             "integrity": "sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==",
             "dev": true,
             "requires": {
-                "chalk": "^2.1.0",
-                "log-symbols": "^2.1.0",
-                "loglevelnext": "^1.0.1",
-                "uuid": "^3.1.0"
+                "chalk": "2.4.2",
+                "log-symbols": "2.2.0",
+                "loglevelnext": "1.0.5",
+                "uuid": "3.3.3"
             },
             "dependencies": {
                 "ansi-styles": {
@@ -17575,7 +17556,7 @@
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "dev": true,
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "chalk": {
@@ -17584,9 +17565,9 @@
                     "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
                     "dev": true,
                     "requires": {
-                        "ansi-styles": "^3.2.1",
-                        "escape-string-regexp": "^1.0.5",
-                        "supports-color": "^5.3.0"
+                        "ansi-styles": "3.2.1",
+                        "escape-string-regexp": "1.0.5",
+                        "supports-color": "5.5.0"
                     }
                 },
                 "supports-color": {
@@ -17595,7 +17576,7 @@
                     "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
                     "dev": true,
                     "requires": {
-                        "has-flag": "^3.0.0"
+                        "has-flag": "3.0.0"
                     }
                 }
             }
@@ -17606,8 +17587,8 @@
             "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
             "dev": true,
             "requires": {
-                "source-list-map": "^2.0.0",
-                "source-map": "~0.6.1"
+                "source-list-map": "2.0.1",
+                "source-map": "0.6.1"
             },
             "dependencies": {
                 "source-map": {
@@ -17624,9 +17605,9 @@
             "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==",
             "dev": true,
             "requires": {
-                "http-parser-js": ">=0.4.0 <0.4.11",
-                "safe-buffer": ">=5.1.0",
-                "websocket-extensions": ">=0.1.1"
+                "http-parser-js": "0.4.10",
+                "safe-buffer": "5.1.2",
+                "websocket-extensions": "0.1.3"
             }
         },
         "websocket-extensions": {
@@ -17661,9 +17642,9 @@
             "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
             "dev": true,
             "requires": {
-                "lodash.sortby": "^4.7.0",
-                "tr46": "^1.0.1",
-                "webidl-conversions": "^4.0.2"
+                "lodash.sortby": "4.7.0",
+                "tr46": "1.0.1",
+                "webidl-conversions": "4.0.2"
             }
         },
         "which": {
@@ -17671,7 +17652,7 @@
             "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
             "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
             "requires": {
-                "isexe": "^2.0.0"
+                "isexe": "2.0.0"
             }
         },
         "which-module": {
@@ -17689,7 +17670,7 @@
             "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
             "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
             "requires": {
-                "string-width": "^1.0.2 || 2"
+                "string-width": "1.0.2"
             }
         },
         "widest-line": {
@@ -17697,7 +17678,7 @@
             "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
             "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
             "requires": {
-                "string-width": "^2.1.1"
+                "string-width": "2.1.1"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -17715,8 +17696,8 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
                     "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
                     "requires": {
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^4.0.0"
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "4.0.0"
                     }
                 },
                 "strip-ansi": {
@@ -17724,7 +17705,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
                     "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
                     "requires": {
-                        "ansi-regex": "^3.0.0"
+                        "ansi-regex": "3.0.0"
                     }
                 }
             }
@@ -17734,8 +17715,8 @@
             "resolved": "https://registry.npmjs.org/wikijs/-/wikijs-6.0.1.tgz",
             "integrity": "sha512-67ZtXyVPspYM5/B5ci0NIwvPJyG23HPk33QQLgLbCcORQ6N0I3Mhxd/KsPRh3xyly87KDs/bh1xuIG6PVTCKGw==",
             "requires": {
-                "cheerio": "^1.0.0-rc.3",
-                "cross-fetch": "^3.0.2",
+                "cheerio": "1.0.0-rc.3",
+                "cross-fetch": "3.0.4",
                 "infobox-parser": "3.3.1"
             }
         },
@@ -17749,8 +17730,8 @@
             "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
             "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
             "requires": {
-                "acorn": "^3.1.0",
-                "acorn-globals": "^3.0.0"
+                "acorn": "3.3.0",
+                "acorn-globals": "3.1.0"
             },
             "dependencies": {
                 "acorn": {
@@ -17771,9 +17752,9 @@
             "resolved": "https://registry.npmjs.org/words-to-numbers/-/words-to-numbers-1.5.1.tgz",
             "integrity": "sha512-uvz7zSCKmmA7o5f5zp4Z5l24RQhy6HSNu10URhNxQWv1I82RsFaZX3qD07RLFUMJsCV38oAuaca13AvhO+9yGw==",
             "requires": {
-                "babel-runtime": "6.x.x",
-                "clj-fuzzy": "^0.3.2",
-                "its-set": "^1.1.5"
+                "babel-runtime": "6.26.0",
+                "clj-fuzzy": "0.3.3",
+                "its-set": "1.2.3"
             }
         },
         "wordwrap": {
@@ -17786,8 +17767,8 @@
             "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
             "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
             "requires": {
-                "reduce-flatten": "^1.0.1",
-                "typical": "^2.6.1"
+                "reduce-flatten": "1.0.1",
+                "typical": "2.6.1"
             }
         },
         "worker-farm": {
@@ -17796,7 +17777,7 @@
             "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
             "dev": true,
             "requires": {
-                "errno": "~0.1.7"
+                "errno": "0.1.7"
             }
         },
         "worker-loader": {
@@ -17804,8 +17785,8 @@
             "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
             "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
             "requires": {
-                "loader-utils": "^1.0.0",
-                "schema-utils": "^0.4.0"
+                "loader-utils": "1.2.3",
+                "schema-utils": "0.4.7"
             }
         },
         "worker-rpc": {
@@ -17814,7 +17795,7 @@
             "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==",
             "dev": true,
             "requires": {
-                "microevent.ts": "~0.1.1"
+                "microevent.ts": "0.1.1"
             }
         },
         "wrap-ansi": {
@@ -17822,8 +17803,8 @@
             "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
             "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
             "requires": {
-                "string-width": "^1.0.1",
-                "strip-ansi": "^3.0.1"
+                "string-width": "1.0.2",
+                "strip-ansi": "3.0.1"
             }
         },
         "wrappy": {
@@ -17836,9 +17817,9 @@
             "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
             "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
             "requires": {
-                "graceful-fs": "^4.1.11",
-                "imurmurhash": "^0.1.4",
-                "signal-exit": "^3.0.2"
+                "graceful-fs": "4.2.0",
+                "imurmurhash": "0.1.4",
+                "signal-exit": "3.0.2"
             }
         },
         "ws": {
@@ -17862,7 +17843,7 @@
             "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.1.9.tgz",
             "integrity": "sha1-wm/Qgm4Bor5xEHSKNPD4OFvkWfE=",
             "requires": {
-                "sax": ">=0.1.1"
+                "sax": "1.2.4"
             }
         },
         "xmlchars": {
@@ -17902,7 +17883,7 @@
             "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz",
             "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==",
             "requires": {
-                "@babel/runtime": "^7.6.3"
+                "@babel/runtime": "7.7.6"
             },
             "dependencies": {
                 "@babel/runtime": {
@@ -17910,7 +17891,7 @@
                     "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.6.tgz",
                     "integrity": "sha512-BWAJxpNVa0QlE5gZdWjSxXtemZyZ9RmrmVozxt3NUXeZhVIJ5ANyqmMc0JDrivBZyxUuQvFxlvH4OWWOogGfUw==",
                     "requires": {
-                        "regenerator-runtime": "^0.13.2"
+                        "regenerator-runtime": "0.13.3"
                     }
                 }
             }
@@ -17920,19 +17901,19 @@
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
             "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
             "requires": {
-                "camelcase": "^3.0.0",
-                "cliui": "^3.2.0",
-                "decamelize": "^1.1.1",
-                "get-caller-file": "^1.0.1",
-                "os-locale": "^1.4.0",
-                "read-pkg-up": "^1.0.1",
-                "require-directory": "^2.1.1",
-                "require-main-filename": "^1.0.1",
-                "set-blocking": "^2.0.0",
-                "string-width": "^1.0.2",
-                "which-module": "^1.0.0",
-                "y18n": "^3.2.1",
-                "yargs-parser": "^5.0.0"
+                "camelcase": "3.0.0",
+                "cliui": "3.2.0",
+                "decamelize": "1.2.0",
+                "get-caller-file": "1.0.3",
+                "os-locale": "1.4.0",
+                "read-pkg-up": "1.0.1",
+                "require-directory": "2.1.1",
+                "require-main-filename": "1.0.1",
+                "set-blocking": "2.0.0",
+                "string-width": "1.0.2",
+                "which-module": "1.0.0",
+                "y18n": "3.2.1",
+                "yargs-parser": "5.0.0"
             },
             "dependencies": {
                 "camelcase": {
@@ -17945,7 +17926,7 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
                     "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
                     "requires": {
-                        "camelcase": "^3.0.0"
+                        "camelcase": "3.0.0"
                     }
                 }
             }
@@ -17955,7 +17936,7 @@
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
             "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
             "requires": {
-                "camelcase": "^4.1.0"
+                "camelcase": "4.1.0"
             }
         },
         "yargs-unparser": {
@@ -17963,9 +17944,9 @@
             "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
             "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
             "requires": {
-                "flat": "^4.1.0",
-                "lodash": "^4.17.15",
-                "yargs": "^13.3.0"
+                "flat": "4.1.0",
+                "lodash": "4.17.15",
+                "yargs": "13.3.0"
             },
             "dependencies": {
                 "ansi-regex": {
@@ -17978,7 +17959,7 @@
                     "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
                     "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
                     "requires": {
-                        "color-convert": "^1.9.0"
+                        "color-convert": "1.9.3"
                     }
                 },
                 "camelcase": {
@@ -17991,9 +17972,9 @@
                     "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
                     "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
                     "requires": {
-                        "string-width": "^3.1.0",
-                        "strip-ansi": "^5.2.0",
-                        "wrap-ansi": "^5.1.0"
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0",
+                        "wrap-ansi": "5.1.0"
                     }
                 },
                 "find-up": {
@@ -18001,7 +17982,7 @@
                     "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
                     "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
                     "requires": {
-                        "locate-path": "^3.0.0"
+                        "locate-path": "3.0.0"
                     }
                 },
                 "get-caller-file": {
@@ -18019,8 +18000,8 @@
                     "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
                     "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
                     "requires": {
-                        "p-locate": "^3.0.0",
-                        "path-exists": "^3.0.0"
+                        "p-locate": "3.0.0",
+                        "path-exists": "3.0.0"
                     }
                 },
                 "p-locate": {
@@ -18028,7 +18009,7 @@
                     "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
                     "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
                     "requires": {
-                        "p-limit": "^2.0.0"
+                        "p-limit": "2.2.2"
                     }
                 },
                 "require-main-filename": {
@@ -18041,9 +18022,9 @@
                     "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
                     "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
                     "requires": {
-                        "emoji-regex": "^7.0.1",
-                        "is-fullwidth-code-point": "^2.0.0",
-                        "strip-ansi": "^5.1.0"
+                        "emoji-regex": "7.0.3",
+                        "is-fullwidth-code-point": "2.0.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "strip-ansi": {
@@ -18051,7 +18032,7 @@
                     "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
                     "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
                     "requires": {
-                        "ansi-regex": "^4.1.0"
+                        "ansi-regex": "4.1.0"
                     }
                 },
                 "which-module": {
@@ -18064,9 +18045,9 @@
                     "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
                     "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
                     "requires": {
-                        "ansi-styles": "^3.2.0",
-                        "string-width": "^3.0.0",
-                        "strip-ansi": "^5.0.0"
+                        "ansi-styles": "3.2.1",
+                        "string-width": "3.1.0",
+                        "strip-ansi": "5.2.0"
                     }
                 },
                 "y18n": {
@@ -18079,16 +18060,16 @@
                     "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
                     "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
                     "requires": {
-                        "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.1"
+                        "cliui": "5.0.0",
+                        "find-up": "3.0.0",
+                        "get-caller-file": "2.0.5",
+                        "require-directory": "2.1.1",
+                        "require-main-filename": "2.0.0",
+                        "set-blocking": "2.0.0",
+                        "string-width": "3.1.0",
+                        "which-module": "2.0.0",
+                        "y18n": "4.0.0",
+                        "yargs-parser": "13.1.1"
                     }
                 },
                 "yargs-parser": {
@@ -18096,8 +18077,8 @@
                     "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
                     "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
                     "requires": {
-                        "camelcase": "^5.0.0",
-                        "decamelize": "^1.2.0"
+                        "camelcase": "5.3.1",
+                        "decamelize": "1.2.0"
                     }
                 }
             }
@@ -18146,9 +18127,9 @@
             "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.2.tgz",
             "integrity": "sha512-ykebHGa2+uzth/R4HZLkZh3XFJzivhVsjJt8bN3GvBzLaqqrUdRacu+c4QtnUgjkkQfsOuNE1JgLKMCPNmkKgg==",
             "requires": {
-                "archiver-utils": "^2.1.0",
-                "compress-commons": "^2.1.1",
-                "readable-stream": "^3.4.0"
+                "archiver-utils": "2.1.0",
+                "compress-commons": "2.1.1",
+                "readable-stream": "3.4.0"
             },
             "dependencies": {
                 "readable-stream": {
@@ -18156,9 +18137,9 @@
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
                     "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
                     "requires": {
-                        "inherits": "^2.0.3",
-                        "string_decoder": "^1.1.1",
-                        "util-deprecate": "^1.0.1"
+                        "inherits": "2.0.3",
+                        "string_decoder": "1.1.1",
+                        "util-deprecate": "1.0.2"
                     }
                 }
             }
diff --git a/src/client/views/ScriptBox.tsx b/src/client/views/ScriptBox.tsx
index ded2329b4..d24256886 100644
--- a/src/client/views/ScriptBox.tsx
+++ b/src/client/views/ScriptBox.tsx
@@ -82,28 +82,19 @@ export class ScriptBox extends React.Component<ScriptBoxProps> {
         );
     }
     //let l = docList(this.source[0].data).length; if (l) { let ind = this.target[0].index !== undefined ? (this.target[0].index+1) % l : 0;  this.target[0].index = ind;  this.target[0].proto = getProto(docList(this.source[0].data)[ind]);}
-    public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, prewrapper?: string, postwrapper?: string) {
+    public static EditButtonScript(title: string, doc: Doc, fieldKey: string, clientX: number, clientY: number, contextParams?: { [name: string]: string }) {
         let overlayDisposer: () => void = emptyFunction;
         const script = ScriptCast(doc[fieldKey]);
         let originalText: string | undefined = undefined;
         if (script) {
             originalText = script.script.originalScript;
-            if (prewrapper && originalText.startsWith(prewrapper)) {
-                originalText = originalText.substr(prewrapper.length);
-            }
-            if (postwrapper && originalText.endsWith(postwrapper)) {
-                originalText = originalText.substr(0, originalText.length - postwrapper.length);
-            }
         }
         // tslint:disable-next-line: no-unnecessary-callback-wrapper
         const params: string[] = [];
         const setParams = (p: string[]) => params.splice(0, params.length, ...p);
         const scriptingBox = <ScriptBox initialText={originalText} setParams={setParams} onCancel={overlayDisposer} onSave={(text, onError) => {
-            if (prewrapper) {
-                text = prewrapper + text + (postwrapper ? postwrapper : "");
-            }
             const script = CompileScript(text, {
-                params: { this: Doc.name },
+                params: { this: Doc.name, ...contextParams },
                 typecheck: false,
                 editable: true,
                 transformer: DocumentIconContainer.getTransformer()
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 0114342b9..a965b2e9b 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, observable } from "mobx";
+import { action, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import "./CollectionSchemaView.scss";
 import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes } from '@fortawesome/free-solid-svg-icons';
@@ -286,7 +286,6 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
     }
 
     @undoBatch
-    @action
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
             const keyOptions = this._searchTerm === "" ? this.props.possibleKeys : this.props.possibleKeys.filter(key => key.toUpperCase().indexOf(this._searchTerm.toUpperCase()) > -1);
@@ -296,7 +295,7 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
             if (!exactFound && this._searchTerm !== "" && this.props.canAddNew) {
                 this.onSelect(this._searchTerm);
             } else {
-                this._searchTerm = this._key;
+                runInAction(() => this._searchTerm = this._key);
             }
         }
     }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c1e36272c..03c757a51 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -22,7 +22,6 @@ import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewField
 import { CollectionSubView } from "./CollectionSubView";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
-import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 import { TraceMobx } from "../../../new_fields/util";
 import { CollectionViewType } from "./CollectionView";
@@ -374,11 +373,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             subItems.push({ description: `${this.props.Document.showTitles ? "Hide Titles" : "Show Titles"}`, event: () => this.props.Document.showTitles = !this.props.Document.showTitles ? "title" : "", icon: "plus" });
             subItems.push({ description: `${this.props.Document.showCaptions ? "Hide Captions" : "Show Captions"}`, event: () => this.props.Document.showCaptions = !this.props.Document.showCaptions ? "caption" : "", icon: "plus" });
             ContextMenu.Instance.addItem({ description: "Stacking Options ...", subitems: subItems, icon: "eye" });
-
-            const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
-            const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
-            onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
-            !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
         }
     }
 
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 79fc477ab..286fdf2bc 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -28,6 +28,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import React = require("react");
 import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
+import { ScriptBox } from '../ScriptBox';
 
 
 export interface TreeViewProps {
@@ -366,8 +367,13 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @action
     bulletClick = (e: React.MouseEvent) => {
-        if (this.props.document.onClick) {
-            ScriptCast(this.props.document.onClick).script.run({ this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document }, console.log);
+        if (this.props.containingCollection.onChildClick) {
+            this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check";
+            ScriptCast(this.props.containingCollection.onChildClick).script.run({
+                this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document,
+                heading: this.props.containingCollection.title,
+                checked: this.props.document.treeViewChecked === "check" ? false : this.props.document.treeViewChecked === "x" ? "x" : "none"
+            }, console.log);
         } else {
             this.treeViewOpen = !this.treeViewOpen;
         }
@@ -376,8 +382,9 @@ class TreeView extends React.Component<TreeViewProps> {
 
     @computed
     get renderBullet() {
-        return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
-            {<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
+        const checked = this.props.containingCollection.onChildClick ? (this.props.document.treeViewChecked ? this.props.document.treeViewChecked : "unchecked") : undefined;
+        return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, checked === "unchecked" ? "white" : "black"), opacity: 0.4 }}>
+            {<FontAwesomeIcon icon={checked === "check" ? "check" : (checked === "x" ? "times" : checked === "unchecked" ? "square" : !this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down"))} />}
         </div>;
     }
     /**
@@ -617,6 +624,10 @@ export class CollectionTreeView extends CollectionSubView(Document) {
             layoutItems.push({ description: (this.props.Document.hideHeaderFields ? "Show" : "Hide") + " Header Fields", event: () => this.props.Document.hideHeaderFields = !this.props.Document.hideHeaderFields, icon: "paint-brush" });
             ContextMenu.Instance.addItem({ description: "Treeview Options ...", subitems: layoutItems, icon: "eye" });
         }
+        const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+        const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+        onClicks.push({ description: "Edit onChecked Script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Checked Changed ...", this.props.Document, "onChildClick", obj.x, obj.y, { heading: "boolean", checked: "boolean" }) });
+        !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
     }
     outerXf = () => Utils.GetScreenTransform(this._mainEle!);
     onTreeDrop = (e: React.DragEvent) => this.onDrop(e, {});
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 88023783b..55f0de779 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -34,6 +34,7 @@ import { FieldViewProps, FieldView } from '../nodes/FieldView';
 import { Touchable } from '../Touchable';
 import { TraceMobx } from '../../../new_fields/util';
 import { Utils } from '../../../Utils';
+import { ScriptBox } from '../ScriptBox';
 const path = require('path');
 library.add(faTh, faTree, faSquare, faProjectDiagram, faSignature, faThList, faFingerprint, faColumns, faEllipsisV, faImage, faEye as any, faCopy);
 
@@ -233,6 +234,11 @@ export class CollectionView extends Touchable<FieldViewProps> {
             const moreItems = more && "subitems" in more ? more.subitems : [];
             moreItems.push({ description: "Export Image Hierarchy", icon: "columns", event: () => ImageUtils.ExportHierarchyToFileSystem(this.props.Document) });
             !more && ContextMenu.Instance.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
+
+            const existingOnClick = ContextMenu.Instance.findByDescription("OnClick...");
+            const onClicks = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
+            onClicks.push({ description: "Edit onChildClick script", icon: "edit", event: (obj: any) => ScriptBox.EditButtonScript("On Child Clicked...", this.props.Document, "onChildClick", obj.x, obj.y) });
+            !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
         }
     }
 
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 184504e5a..996c7671e 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -217,9 +217,10 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
             "true";
 
-        const docFilter = StrCast(this.props.CollectionView.props.Document.docFilter);
-        const finalScript = docFilter && !fullScript.startsWith("(())") ? `${fullScript} ${docFilter ? "&&" : ""} (${docFilter})` :
-            docFilter ? docFilter : fullScript;
+        const docFilter = Cast(this.props.CollectionView.props.Document.docFilter, listSpec("string"), []);
+        const docFilterText = Doc.MakeDocFilter(docFilter);
+        const finalScript = docFilterText && !fullScript.startsWith("(())") ? `${fullScript} ${docFilterText ? "&&" : ""} (${docFilterText})` :
+            docFilterText ? docFilterText : fullScript;
 
         this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(finalScript, { doc: Doc.name });
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index ba35366ff..e45c19533 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -196,7 +196,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY);
             } else if (this.props.Document.isButton === "Selector") {  // this should be moved to an OnClick script
                 FormattedTextBoxComment.Hide();
-                this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0], this.props.Document)]));
+                this.Document.links?.[0] instanceof Doc && (Doc.UserDoc().SelectedDocs = new List([Doc.LinkOtherAnchor(this.Document.links[0]!, this.props.Document)]));
             } else if (this.Document.isButton) {
                 SelectionManager.SelectDoc(this, e.ctrlKey); // don't think this should happen if a button action is actually triggered.
                 this.buttonClick(e.altKey, e.ctrlKey);
@@ -815,10 +815,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
             }}>
                 <EditableView ref={this._titleRef}
-                    contents={this.Document[showTitle]}
+                    contents={(this.props.DataDoc || this.props.Document)[showTitle]}
                     display={"block"} height={72} fontSize={12}
-                    GetValue={() => StrCast(this.Document[showTitle])}
-                    SetValue={undoBatch((value: string) => (Doc.GetProto(this.Document)[showTitle] = value) ? true : true)}
+                    GetValue={() => StrCast((this.props.DataDoc || this.props.Document)[showTitle])}
+                    SetValue={undoBatch((value: string) => (Doc.GetProto(this.props.DataDoc || this.props.Document)[showTitle] = value) ? true : true)}
                 />
             </div>);
         return <>
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 8117453e7..32ab36c0f 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -742,8 +742,19 @@ export namespace Doc {
             source.dragFactory instanceof Doc && source.dragFactory.isTemplateDoc ? source.dragFactory :
             source && source.layout instanceof Doc && source.layout.isTemplateDoc ? source.layout : undefined;
     }
-}
 
+    export function MakeDocFilter(docFilters: string[]) {
+        let docFilterText = "";
+        for (let i = 0; i < docFilters.length; i += 3) {
+            const key = docFilters[i];
+            const value = docFilters[i + 1];
+            const modifiers = docFilters[i + 2];
+            const scriptText = `${modifiers === "x" ? "!" : ""}matchFieldValue(doc, "${key}", "${value}")`;
+            docFilterText = docFilterText ? docFilterText + " && " + scriptText : scriptText;
+        };
+        return docFilterText ? "(" + docFilterText + ")" : "";
+    }
+}
 
 Scripting.addGlobal(function renameAlias(doc: any, n: any) { return StrCast(Doc.GetProto(doc).title).replace(/\([0-9]*\)/, "") + `(${n})`; });
 Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
@@ -761,9 +772,31 @@ Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: bo
     const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)));
     return docs.length ? new List(docs) : prevValue;
 });
-Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, type: string, contains: boolean = true) {
-    const scriptText = `${contains ? "" : "!"}(((doc.${key} && (doc.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))) ||
-    ((doc.data_ext && doc.data_ext.${key}) && (doc.data_ext.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))))`;
-    container.docFilter = scriptText;
-    container.viewSpecScript = ScriptField.MakeFunction(scriptText, { doc: Doc.name });
+Scripting.addGlobal(function matchFieldValue(doc: Doc, key: string, value: any) {
+    const fieldVal = doc[key] ? doc[key] : doc[key + "_ext"];
+    if (StrCast(fieldVal, null) !== undefined) return StrCast(fieldVal) === value;
+    if (NumCast(fieldVal, null) !== undefined) return NumCast(fieldVal) === value;
+    if (Cast(fieldVal, listSpec("string"), []).length) {
+        let vals = Cast(fieldVal, listSpec("string"), []);
+        return vals.some(v => v === value);
+    }
+    return false;
+});
+Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers: string) {
+    const docFilters = Cast(container.docFilter, listSpec("string"), []);
+    let found = false;
+    for (let i = 0; i < docFilters.length && !found; i += 3) {
+        if (docFilters[i] === key && docFilters[i + 1] === value) {
+            found = true;
+            docFilters.splice(i, 3);
+        }
+    }
+    if (!found || modifiers !== "none") {
+        docFilters.push(key);
+        docFilters.push(value);
+        docFilters.push(modifiers);
+        container.docFilter = new List<string>(docFilters);
+    }
+    const docFilterText = Doc.MakeDocFilter(docFilters);
+    container.viewSpecScript = docFilterText ? ScriptField.MakeFunction(docFilterText, { doc: Doc.name }) : undefined;
 });
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 15f2148f40c351589e18c1f9ac3b39a8de366a40 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 14 Jan 2020 17:15:36 -0500
Subject: fixes for stacking views to honor panelwidth/height -- allows
 stacking panels to  be placed in Content fitting document views.

---
 src/client/documents/Documents.ts                  |  2 +-
 .../views/collections/CollectionStackingView.tsx   | 31 +++++-----
 src/client/views/nodes/DocumentContentsView.tsx    |  2 +-
 src/client/views/nodes/ImageBox.tsx                | 69 ++++++++++------------
 src/new_fields/Doc.ts                              | 18 +++---
 5 files changed, 60 insertions(+), 62 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e149963b9..be678d765 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -355,7 +355,7 @@ export namespace Docs {
 
             AudioBox.ActiveRecordings.map(d => DocUtils.MakeLink({ doc: viewDoc }, { doc: d }, "audio link", "link to audio: " + d.title));
 
-            return Doc.assign(viewDoc, delegateProps);
+            return Doc.assign(viewDoc, delegateProps, true);
         }
 
         /**
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 03c757a51..3ab0326e2 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -39,7 +39,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
-    @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
+    @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized).map(d => (Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d).layout as Doc) || d); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return Math.max(this.props.Document.showTitle ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@@ -52,22 +52,18 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
 
-    childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
-
     children(docs: Doc[]) {
         this._docXfs.length = 0;
         return docs.map((d, i) => {
-            const pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
-            const layoutDoc = pair.layout ? Doc.Layout(pair.layout) : d;
-            const width = () => Math.min(layoutDoc.nativeWidth && !layoutDoc.ignoreAspect && !this.props.Document.fillColumn ? layoutDoc[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
-            const height = () => this.getDocHeight(layoutDoc);
+            const width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
+            const height = () => this.getDocHeight(d);
             const dref = React.createRef<HTMLDivElement>();
-            const dxf = () => this.getDocTransform(layoutDoc, dref.current!);
+            const dxf = () => this.getDocTransform(d, dref.current!);
             this._docXfs.push({ dxf: dxf, width: width, height: height });
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
             const style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
-                {this.getDisplayDoc(pair.layout || d, pair.data, dxf, width)}
+                {this.getDisplayDoc(d, (d.resolvedDataDoc as Doc) || d, dxf, width)}
             </div>;
         });
     }
@@ -114,7 +110,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     const res = this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => {
                         const r1 = Math.max(maxHght,
                             (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => {
-                                const val = height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap);
+                                const val = height + this.getDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap);
                                 return val;
                             }, this.yMargin));
                         return r1;
@@ -291,7 +287,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
         const key = this.sectionFilter;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
-        const types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
+        const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
         if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
             type = types[0];
         }
@@ -316,15 +312,17 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         const y = this._scroll; // required for document decorations to update when the text box container is scrolled
         const { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
         const outerXf = Utils.GetScreenTransform(this._masonryGridRef!);
+        const scaling = 1 / Math.min(1, this.props.PanelHeight() / this.layoutDoc[HeightSym]());
         const offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
-        return this.props.ScreenToLocalTransform().
-            translate(offset[0], offset[1] + (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0));
+        const offsetx = (doc[WidthSym]() - doc[WidthSym]() / scaling) / 2;
+        const offsety = (this.props.ChromeHeight && this.props.ChromeHeight() < 0 ? this.props.ChromeHeight() : 0);
+        return this.props.ScreenToLocalTransform().translate(offset[0] - offsetx, offset[1] + offsety).scale(scaling);
     }
 
     sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
         const key = this.sectionFilter;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
-        const types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
+        const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
         if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
             type = types[0];
         }
@@ -396,6 +394,11 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             <div className="collectionStackingMasonry-cont" >
                 <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
                     ref={this.createRef}
+                    style={{
+                        transform: `scale(${Math.min(1, this.props.PanelHeight() / this.layoutDoc[HeightSym]())})`,
+                        height: `${100 * 1 / Math.min(this.props.PanelWidth() / this.layoutDoc[WidthSym](), this.props.PanelHeight() / this.layoutDoc[HeightSym]())}%`,
+                        transformOrigin: "top"
+                    }}
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
                     onDrop={this.onDrop.bind(this)}
                     onContextMenu={this.onContextMenu}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 8f6bfc8e1..66886165e 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -82,7 +82,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
         return this.props.DataDoc;
     }
     get layoutDoc() {
-        return this.props.DataDoc === undefined ? Doc.expandTemplateLayout(Doc.Layout(this.props.Document), this.props.Document) : Doc.Layout(this.props.Document);
+        return Doc.expandTemplateLayout(Doc.Layout(this.props.Document), this.props.Document);
     }
 
     CreateBindings(): JsxBindings {
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 09e627078..634555012 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -214,37 +214,23 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
     }
     _curSuffix = "_m";
 
-    _resized = false;
-    resize = (srcpath: string) => {
-        requestImageSize(srcpath)
+    _resized = "";
+    resize = (imgPath: string) => {
+        requestImageSize(imgPath)
             .then((size: any) => {
                 const rotation = NumCast(this.dataDoc.rotation) % 180;
                 const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
                 const aspect = realsize.height / realsize.width;
                 if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) {
                     setTimeout(action(() => {
-                        this._resized = true;
-                        this.Document.height = this.Document[WidthSym]() * aspect;
-                        this.Document.nativeHeight = realsize.height;
-                        this.Document.nativeWidth = realsize.width;
+                        if (this.pathInfos.srcpath === imgPath && (!this.layoutDoc.isTemplateDoc || this.dataDoc !== this.layoutDoc)) {
+                            this._resized = imgPath;
+                            this.Document.height = this.Document[WidthSym]() * aspect;
+                            this.Document.nativeHeight = realsize.height;
+                            this.Document.nativeWidth = realsize.width;
+                        }
                     }), 0);
-                } else this._resized = true;
-            })
-            .catch((err: any) => console.log(err));
-    }
-    fadesize = (srcpath: string) => {
-        requestImageSize(srcpath)
-            .then((size: any) => {
-                const rotation = NumCast(this.dataDoc.rotation) % 180;
-                const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
-                const aspect = realsize.height / realsize.width;
-                if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) {
-                    setTimeout(action(() => {
-                        this.Document.height = this.Document[WidthSym]() * aspect;
-                        this.Document.nativeHeight = realsize.height;
-                        this.Document.nativeWidth = realsize.width;
-                    }), 0);
-                }
+                } else this._resized = imgPath;
             })
             .catch((err: any) => console.log(err));
     }
@@ -285,18 +271,16 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         return !tags ? (null) : (<img id={"google-tags"} src={"/assets/google_tags.png"} />);
     }
 
-    @computed get content() {
-        TraceMobx();
-        const extensionDoc = this.extensionDoc;
-        if (!extensionDoc) return (null);
-        // let transform = this.props.ScreenToLocalTransform().inverse();
+    @computed get nativeSize() {
         const pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
-        // var [sptX, sptY] = transform.transformPoint(0, 0);
-        // let [bptX, bptY] = transform.transformPoint(pw, this.props.PanelHeight());
-        // let w = bptX - sptX;
-
         const nativeWidth = (this.Document.nativeWidth || pw);
         const nativeHeight = (this.Document.nativeHeight || 1);
+        return { nativeWidth, nativeHeight };
+    }
+
+    @computed get pathInfos() {
+        const extensionDoc = this.extensionDoc!;
+        const { nativeWidth, nativeHeight } = this.nativeSize;
         let paths = [[Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png"), nativeWidth / nativeHeight]];
         // this._curSuffix = "";
         // if (w > 20) {
@@ -308,15 +292,24 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         // else if (this._largeRetryCount < 10) this._curSuffix = "_l";
         if (field instanceof ImageField) paths = [[this.choosePath(field.url), nativeWidth / nativeHeight]];
         paths.push(...altpaths);
-        // }
-        const rotation = NumCast(this.Document.rotation, 0);
-        const aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
-        const shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
         const srcpath = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][0] as string;
         const srcaspect = paths[Math.min(paths.length - 1, (this.Document.curPage || 0))][1] as number;
         const fadepath = paths[Math.min(paths.length - 1, 1)][0] as string;
+        return { srcpath, srcaspect, fadepath };
+    }
+
+    @computed get content() {
+        TraceMobx();
+        const extensionDoc = this.extensionDoc;
+        if (!extensionDoc) return (null);
+
+        const { srcpath, srcaspect, fadepath } = this.pathInfos;
+        const { nativeWidth, nativeHeight } = this.nativeSize;
+        const rotation = NumCast(this.Document.rotation, 0);
+        const aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
+        const shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
 
-        !this.Document.ignoreAspect && !this._resized && this.resize(srcpath);
+        !this.Document.ignoreAspect && this._resized !== srcpath && this.resize(srcpath);
 
         return <div className="imageBox-cont" key={this.props.Document[Id]} ref={this.createDropTarget} onContextMenu={this.specificContextMenu}>
             <div className="imageBox-fader" >
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index c809ad17a..d4634ba4b 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -290,14 +290,13 @@ export namespace Doc {
      * @param fields the fields to project onto the target. Its type signature defines a mapping from some string key
      * to a potentially undefined field, where each entry in this mapping is optional. 
      */
-    export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>) {
+    export function assign<K extends string>(doc: Doc, fields: Partial<Record<K, Opt<Field>>>, skipUndefineds: boolean = false) {
         for (const key in fields) {
             if (fields.hasOwnProperty(key)) {
                 const value = fields[key];
-                // Do we want to filter out undefineds?
-                // if (value !== undefined) {
-                doc[key] = value;
-                // }
+                if (!skipUndefineds || value !== undefined) { // Do we want to filter out undefineds?
+                    doc[key] = value;
+                }
             }
         }
         return doc;
@@ -406,8 +405,9 @@ export namespace Doc {
     }
     export function MakeAlias(doc: Doc) {
         const alias = !GetT(doc, "isPrototype", "boolean", true) ? Doc.MakeCopy(doc) : Doc.MakeDelegate(doc);
-        if (alias.layout instanceof Doc) {
-            alias.layout = Doc.MakeAlias(alias.layout);
+        let layout = Doc.Layout(alias);
+        if (layout instanceof Doc && layout !== alias) {
+            Doc.SetLayout(alias, Doc.MakeAlias(layout));
         }
         const aliasNumber = Doc.GetProto(doc).aliasNumber = NumCast(Doc.GetProto(doc).aliasNumber) + 1;
         alias.title = ComputedField.MakeFunction(`renameAlias(this, ${aliasNumber})`);
@@ -455,6 +455,7 @@ export namespace Doc {
         if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
             const extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
             layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined);
+            layoutDoc && (layoutDoc.resolvedDataDoc = resolvedDataDoc);
         } else layoutDoc = childDocLayout;
         return { layout: layoutDoc, data: resolvedDataDoc };
     }
@@ -468,7 +469,7 @@ export namespace Doc {
     //
     export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
         const extension = doc[fieldKey + "_ext"];
-        if (extension === undefined) {
+        if (doc instanceof Doc && extension === undefined) {
             setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
         }
         return extension ? extension as Doc : undefined;
@@ -657,6 +658,7 @@ export namespace Doc {
     // the document containing the view layout information - will be the Document itself unless the Document has
     // a layout field.  In that case, all layout information comes from there unless overriden by Document  
     export function Layout(doc: Doc) { return Doc.LayoutField(doc) instanceof Doc ? doc[StrCast(doc.layoutKey, "layout")] as Doc : doc; }
+    export function SetLayout(doc: Doc, layout: Doc | string) { doc[StrCast(doc.layoutKey, "layout")] = layout; }
     export function LayoutField(doc: Doc) { return doc[StrCast(doc.layoutKey, "layout")]; }
     const manager = new DocData();
     export function SearchQuery(): string { return manager._searchQuery; }
-- 
cgit v1.2.3-70-g09d2


From de0c00ff0bb1f58a0736da24acc984f5a090d009 Mon Sep 17 00:00:00 2001
From: Stanley Yip <stanley_yip@brown.edu>
Date: Tue, 14 Jan 2020 18:35:28 -0500
Subject: ok we now use custom events for touch. im struggling with figuring
 out how to ignore a hand lol

---
 src/client/util/InteractionUtils.ts                |  50 ++++++-
 src/client/views/CollectionLinearView.tsx          |   4 +-
 src/client/views/GestureOverlay.tsx                | 160 +++++++++++++++++++--
 src/client/views/Touchable.tsx                     | 114 ++++++++++-----
 .../views/collections/CollectionStackingView.tsx   |   6 +-
 src/client/views/collections/CollectionSubView.tsx |   8 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  80 ++++++-----
 src/client/views/nodes/DocumentView.tsx            |  32 +++--
 src/pen-gestures/GestureUtils.ts                   |   2 +-
 9 files changed, 344 insertions(+), 112 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/util/InteractionUtils.ts b/src/client/util/InteractionUtils.ts
index 76b43da3c..63ee2fb92 100644
--- a/src/client/util/InteractionUtils.ts
+++ b/src/client/util/InteractionUtils.ts
@@ -8,13 +8,53 @@ export namespace InteractionUtils {
     const REACT_POINTER_PEN_BUTTON = 0;
     const ERASER_BUTTON = 5;
 
+    export class MultiTouchEvent<T extends React.TouchEvent | TouchEvent> {
+        constructor(
+            readonly fingers: number,
+            readonly points: T extends React.TouchEvent ? React.TouchList : TouchList,
+            readonly touchEvent: T extends React.TouchEvent ? React.TouchEvent : TouchEvent
+        ) { }
+    }
+
+    export interface MultiTouchEventDisposer { (): void; }
+
+    export function MakeMultiTouchTarget(
+        element: HTMLElement,
+        startFunc: (e: Event, me: MultiTouchEvent<React.TouchEvent>) => void,
+    ): MultiTouchEventDisposer {
+        const onMultiTouchStartHandler = (e: Event) => startFunc(e, (e as CustomEvent<MultiTouchEvent<React.TouchEvent>>).detail);
+        // const onMultiTouchMoveHandler = moveFunc ? (e: Event) => moveFunc(e, (e as CustomEvent<MultiTouchEvent<TouchEvent>>).detail) : undefined;
+        // const onMultiTouchEndHandler = endFunc ? (e: Event) => endFunc(e, (e as CustomEvent<MultiTouchEvent<TouchEvent>>).detail) : undefined;
+        element.addEventListener("dashOnTouchStart", onMultiTouchStartHandler);
+        // if (onMultiTouchMoveHandler) {
+        //     element.addEventListener("dashOnTouchMove", onMultiTouchMoveHandler);
+        // }
+        // if (onMultiTouchEndHandler) {
+        //     element.addEventListener("dashOnTouchEnd", onMultiTouchEndHandler);
+        // }
+        return () => {
+            element.removeEventListener("dashOnTouchStart", onMultiTouchStartHandler);
+            // if (onMultiTouchMoveHandler) {
+            //     element.removeEventListener("dashOnTouchMove", onMultiTouchMoveHandler);
+            // }
+            // if (onMultiTouchEndHandler) {
+            //     element.removeEventListener("dashOnTouchend", onMultiTouchEndHandler);
+            // }
+        };
+    }
+
     export function GetMyTargetTouches(e: TouchEvent | React.TouchEvent, prevPoints: Map<number, React.Touch>, ignorePen: boolean): React.Touch[] {
         const myTouches = new Array<React.Touch>();
-        for (let i = 0; i < e.targetTouches.length; i++) {
-            const pt: any = e.targetTouches.item(i);
-            if (pt && prevPoints.has(pt.identifier)) {
-                if (ignorePen || (pt.radiusX > 1 && pt.radiusY > 1)) {
-                    myTouches.push(pt);
+        for (let i = 0; i < e.touches.length; i++) {
+            const pt: any = e.touches.item(i);
+            if (ignorePen || (pt.radiusX > 1 && pt.radiusY > 1)) {
+                for (let j = 0; j < e.targetTouches.length; j++) {
+                    const tPt = e.targetTouches.item(j);
+                    if (tPt?.screenX === pt?.screenX && tPt?.screenY === pt?.screenY) {
+                        if (pt && prevPoints.has(pt.identifier)) {
+                            myTouches.push(pt);
+                        }
+                    }
                 }
             }
         }
diff --git a/src/client/views/CollectionLinearView.tsx b/src/client/views/CollectionLinearView.tsx
index 5d6a58656..38f2decdd 100644
--- a/src/client/views/CollectionLinearView.tsx
+++ b/src/client/views/CollectionLinearView.tsx
@@ -36,7 +36,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
             { fireImmediately: true }
         );
     }
-    protected createDropAndGestureTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+    protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
         this._dropDisposer && this._dropDisposer();
         if (ele) {
             this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
@@ -55,7 +55,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
     render() {
         const guid = Utils.GenerateGuid();
         return <div className="collectionLinearView-outer">
-            <div className="collectionLinearView" ref={this.createDropAndGestureTarget} >
+            <div className="collectionLinearView" ref={this.createDashEventsTarget} >
                 <input id={`${guid}`} type="checkbox" checked={BoolCast(this.props.Document.isExpanded)} ref={this.addMenuToggle}
                     onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
                 <label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 830c06f1f..a5fba362c 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -1,7 +1,7 @@
 import React = require("react");
 import { Touchable } from "./Touchable";
 import { observer } from "mobx-react";
-import "./GestureOverlay.scss"
+import "./GestureOverlay.scss";
 import { computed, observable, action, runInAction } from "mobx";
 import { CreatePolyline } from "./InkingStroke";
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
@@ -16,6 +16,7 @@ import { Scripting } from "../util/Scripting";
 import { FieldValue, Cast } from "../../new_fields/Types";
 import { CurrentUserUtils } from "../../server/authentication/models/current_user_utils";
 import Palette from "./Palette";
+import { Utils } from "../../Utils";
 
 @observer
 export default class GestureOverlay extends Touchable {
@@ -28,6 +29,9 @@ export default class GestureOverlay extends Touchable {
 
     private _d1: Doc | undefined;
     private thumbIdentifier?: number;
+    private _hands: (React.Touch[])[] = [];
+
+    protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
 
     constructor(props: Readonly<{}>) {
         super(props);
@@ -35,11 +39,143 @@ export default class GestureOverlay extends Touchable {
         GestureOverlay.Instance = this;
     }
 
-    @action
+    getNewTouches(e: React.TouchEvent | TouchEvent) {
+        const ntt: (React.Touch | Touch)[] = [];
+        const nct: (React.Touch | Touch)[] = [];
+        const nt: (React.Touch | Touch)[] = [];
+        this._hands.forEach((hand) => {
+            for (let i = 0; i < e.targetTouches.length; i++) {
+                const pt = e.targetTouches.item(i);
+                if (pt && !hand.some((finger) => finger.screenX === pt?.screenX && finger.screenY === pt.screenY)) {
+                    ntt.push(pt);
+                }
+            }
+
+            for (let i = 0; i < e.changedTouches.length; i++) {
+                const pt = e.changedTouches.item(i);
+                if (pt && !hand.some((finger: React.Touch) => finger.screenX === pt?.screenX && finger.screenY === pt.screenY)) {
+                    nct.push(pt);
+                }
+            }
+
+            for (let i = 0; i < e.changedTouches.length; i++) {
+                const pt = e.touches.item(i);
+                if (pt && !hand.some((finger: React.Touch) => finger.screenX === pt?.screenX && finger.screenY === pt.screenY)) {
+                    nt.push(pt);
+                }
+            }
+        });
+        return { ntt, nct, nt };
+    }
+
+    onReactTouchStart = (te: React.TouchEvent) => {
+        const actualPts: React.Touch[] = [];
+        for (let i = 0; i < te.touches.length; i++) {
+            const pt: any = te.touches.item(i);
+            actualPts.push(pt);
+            // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
+            // and this seems to be the only way of differentiating pen and touch on touch events
+            if (pt.radiusX > 1 && pt.radiusY > 1) {
+                // if (typeof pt.identifier !== "string") {
+                //     pt.identifier = Utils.GenerateGuid();
+                // }
+                this.prevPoints.set(pt.identifier, pt);
+            }
+        }
+
+        const ptsToDelete: number[] = [];
+        this.prevPoints.forEach(pt => {
+            if (!actualPts.includes(pt)) {
+                ptsToDelete.push(pt.identifier);
+            }
+        });
+
+        ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
+
+        if (this.prevPoints.size && this.prevPoints.size < 5) {
+            const nts: any = this.getNewTouches(te);
+            const target = document.elementFromPoint(te.changedTouches.item(0).clientX, te.changedTouches.item(0).clientY);
+            target?.dispatchEvent(
+                new CustomEvent<InteractionUtils.MultiTouchEvent<React.TouchEvent>>("dashOnTouchStart",
+                    {
+                        bubbles: true,
+                        detail: {
+                            fingers: this.prevPoints.size,
+                            points: te.targetTouches,
+                            touchEvent: new React.TouchEvent("start", {
+                                targetTouches: nts.ntt,
+                                touches: nts.nt,
+                                changedTouches: nts.nct
+                            });
+                        }
+                    }
+                )
+            );
+            document.removeEventListener("touchmove", this.onReactTouchMove);
+            document.removeEventListener("touchend", this.onReactTouchEnd);
+            document.addEventListener("touchmove", this.onReactTouchMove);
+            document.addEventListener("touchend", this.onReactTouchEnd);
+        }
+        else {
+            this.handleHandDown(te);
+            document.removeEventListener("touchmove", this.onReactTouchMove);
+            document.removeEventListener("touchend", this.onReactTouchEnd);
+        }
+    }
+
+    onReactTouchMove = (e: TouchEvent) => {
+        const nts: any = this.getNewTouches(e);
+        document.dispatchEvent(
+            new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchMove",
+                {
+                    bubbles: true,
+                    detail: {
+                        fingers: this.prevPoints.size,
+                        points: e.touches,
+                        touchEvent: new TouchEvent("move", {
+                            targetTouches: nts.ntt,
+                            changedTouches: nts.nct,
+                            touches: nts.nt,
+                        })
+                    }
+                })
+        );
+    }
+
+    onReactTouchEnd = (e: TouchEvent) => {
+        document.dispatchEvent(
+            new CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>("dashOnTouchEnd",
+                {
+                    bubbles: true,
+                    detail: {
+                        fingers: this.prevPoints.size,
+                        points: e.touches,
+                        touchEvent: e
+                    }
+                })
+        );
+        for (let i = 0; i < e.changedTouches.length; i++) {
+            const pt = e.changedTouches.item(i);
+            if (pt) {
+                if (this.prevPoints.has(pt.identifier)) {
+                    this.prevPoints.delete(pt.identifier);
+                }
+            }
+        }
+
+        if (this.prevPoints.size === 0) {
+            document.removeEventListener("touchmove", this.onReactTouchMove);
+            document.removeEventListener("touchend", this.onReactTouchEnd);
+        }
+        e.stopPropagation();
+    }
+
     handleHandDown = (e: React.TouchEvent) => {
         const fingers = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true);
         const thumb = fingers.reduce((a, v) => a.clientY > v.clientY ? a : v, fingers[0]);
         this.thumbIdentifier = thumb?.identifier;
+        fingers.forEach((f) => this.prevPoints.delete(f.identifier));
+        this._hands.push(fingers);
         const others = fingers.filter(f => f !== thumb);
         const minX = Math.min(...others.map(f => f.clientX));
         const minY = Math.min(...others.map(f => f.clientY));
@@ -48,10 +184,12 @@ export default class GestureOverlay extends Touchable {
 
         const thumbDoc = FieldValue(Cast(CurrentUserUtils.setupThumbDoc(CurrentUserUtils.UserDocument), Doc));
         if (thumbDoc) {
-            this._palette = <Palette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
+            runInAction(() => {
+                this._palette = <Palette x={minX} y={minY} thumb={[thumb.clientX, thumb.clientY]} thumbDoc={thumbDoc} />;
+            });
         }
 
-        document.removeEventListener("touchmove", this.onTouch);
+        this.removeMoveListeners();
         document.removeEventListener("touchmove", this.handleHandMove);
         document.addEventListener("touchmove", this.handleHandMove);
         document.removeEventListener("touchend", this.handleHandUp);
@@ -69,11 +207,9 @@ export default class GestureOverlay extends Touchable {
 
     @action
     handleHandUp = (e: TouchEvent) => {
-        this.onTouchEnd(e);
-        if (this.prevPoints.size < 3) {
-            this._palette = undefined;
-            document.removeEventListener("touchend", this.handleHandUp);
-        }
+        // this.onTouchEnd(e);
+        this._palette = undefined;
+        document.removeEventListener("touchend", this.handleHandUp);
     }
 
     @action
@@ -115,7 +251,7 @@ export default class GestureOverlay extends Touchable {
                 DocUtils.MakeLink({ doc: this._d1 }, { doc: doc });
                 actionPerformed = true;
             }
-        }
+        };
         const ge = new CustomEvent<GestureUtils.GestureEvent>("dashOnGesture",
             {
                 bubbles: true,
@@ -181,7 +317,7 @@ export default class GestureOverlay extends Touchable {
                             }
                         }
                     )
-                )
+                );
                 this._points = [];
             }
         }
@@ -215,7 +351,7 @@ export default class GestureOverlay extends Touchable {
 
     render() {
         return (
-            <div className="gestureOverlay-cont" onPointerDown={this.onPointerDown} onTouchStart={this.onTouchStart}>
+            <div className="gestureOverlay-cont" onPointerDown={this.onPointerDown} onTouchStart={this.onReactTouchStart}>
                 {this.props.children}
                 {this._palette}
                 {this.currentStroke}
diff --git a/src/client/views/Touchable.tsx b/src/client/views/Touchable.tsx
index 2a7599fbf..a71015b05 100644
--- a/src/client/views/Touchable.tsx
+++ b/src/client/views/Touchable.tsx
@@ -8,8 +8,11 @@ const HOLD_DURATION = 1000;
 
 export abstract class Touchable<T = {}> extends React.Component<T> {
     //private holdTimer: NodeJS.Timeout | undefined;
-    holdTimer: NodeJS.Timeout | undefined;
+    private holdTimer: NodeJS.Timeout | undefined;
+    private moveDisposer?: InteractionUtils.MultiTouchEventDisposer;
+    private endDisposer?: InteractionUtils.MultiTouchEventDisposer;
 
+    protected abstract multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
     protected _touchDrag: boolean = false;
     protected prevPoints: Map<number, React.Touch> = new Map<number, React.Touch>();
 
@@ -22,16 +25,27 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
      * When a touch even starts, we keep track of each touch that is associated with that event
      */
     @action
-    protected onTouchStart = (e: React.TouchEvent): void => {
+    protected onTouchStart = (e: Event, me: InteractionUtils.MultiTouchEvent<React.TouchEvent>): void => {
         const actualPts: React.Touch[] = [];
-        for (let i = 0; i < e.targetTouches.length; i++) {
-            const pt: any = e.targetTouches.item(i);
+        const te = me.touchEvent;
+        // loop through all touches on screen
+        for (let i = 0; i < te.touches.length; i++) {
+            const pt: any = te.touches.item(i);
             actualPts.push(pt);
-            // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
-            // and this seems to be the only way of differentiating pen and touch on touch events
-            if (pt.radiusX > 1 && pt.radiusY > 1) {
+            if (this.prevPoints.has(pt.identifier)) {
                 this.prevPoints.set(pt.identifier, pt);
             }
+            // only add the ones that are targeted on "this" element, but with the identifier that the screen touch gives
+            for (let j = 0; j < te.changedTouches.length; j++) {
+                const tPt = te.changedTouches.item(j);
+                if (pt.clientX === tPt.clientX && pt.clientY === tPt.clientY) {
+                    // pen is also a touch, but with a radius of 0.5 (at least with the surface pens)
+                    // and this seems to be the only way of differentiating pen and touch on touch events
+                    if (pt.radiusX > 1 && pt.radiusY > 1) {
+                        this.prevPoints.set(pt.identifier, pt);
+                    }
+                }
+            }
         }
 
         const ptsToDelete: number[] = [];
@@ -41,26 +55,30 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
             }
         });
 
+        // console.log(ptsToDelete.length);
         ptsToDelete.forEach(pt => this.prevPoints.delete(pt));
 
+        // console.log(this.prevPoints.size);
         if (this.prevPoints.size) {
             switch (this.prevPoints.size) {
                 case 1:
-                    this.handle1PointerDown(e);
-                    e.persist();
+                    this.handle1PointerDown(te);
+                    te.persist();
                     // if (this.holdTimer) {
                     //     clearTimeout(this.holdTimer)
                     //     this.holdTimer = undefined;
                     // }
-                    this.holdTimer = setTimeout(() => this.handle1PointerHoldStart(e), HOLD_DURATION);
+                    this.holdTimer = setTimeout(() => this.handle1PointerHoldStart(te), HOLD_DURATION);
+                    // e.stopPropagation();
                     // console.log(this.holdTimer);
                     break;
                 case 2:
-                    this.handle2PointersDown(e);
-                    break;
-                case 5:
-                    this.handleHandDown(e);
+                    this.handle2PointersDown(te);
+                    // e.stopPropagation();
                     break;
+                // case 5:
+                //     this.handleHandDown(te);
+                //     break;
             }
         }
     }
@@ -69,28 +87,30 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
     * Handle touch move event
     */
     @action
-    protected onTouch = (e: TouchEvent): void => {
-        const myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true);
+    protected onTouch = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
+        const te = me.touchEvent;
+        const myTouches = InteractionUtils.GetMyTargetTouches(te, this.prevPoints, true);
 
         // if we're not actually moving a lot, don't consider it as dragging yet
         if (!InteractionUtils.IsDragging(this.prevPoints, myTouches, 5) && !this._touchDrag) return;
         this._touchDrag = true;
         if (this.holdTimer) {
-            console.log("CLEAR")
+            console.log("CLEAR");
             clearTimeout(this.holdTimer);
             // this.holdTimer = undefined;
         }
+        // console.log(myTouches.length);
         switch (myTouches.length) {
             case 1:
-                this.handle1PointerMove(e);
+                this.handle1PointerMove(te);
                 break;
             case 2:
-                this.handle2PointersMove(e);
+                this.handle2PointersMove(te);
                 break;
         }
 
-        for (let i = 0; i < e.targetTouches.length; i++) {
-            const pt = e.targetTouches.item(i);
+        for (let i = 0; i < te.touches.length; i++) {
+            const pt = te.touches.item(i);
             if (pt) {
                 if (this.prevPoints.has(pt.identifier)) {
                     this.prevPoints.set(pt.identifier, pt);
@@ -100,11 +120,12 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
     }
 
     @action
-    protected onTouchEnd = (e: TouchEvent): void => {
+    protected onTouchEnd = (e: Event, me: InteractionUtils.MultiTouchEvent<TouchEvent>): void => {
         // console.log(InteractionUtils.GetMyTargetTouches(e, this.prevPoints).length + " up");
         // remove all the touches associated with the event
-        for (let i = 0; i < e.changedTouches.length; i++) {
-            const pt = e.changedTouches.item(i);
+        const te = me.touchEvent;
+        for (let i = 0; i < te.changedTouches.length; i++) {
+            const pt = te.changedTouches.item(i);
             if (pt) {
                 if (this.prevPoints.has(pt.identifier)) {
                     this.prevPoints.delete(pt.identifier);
@@ -116,7 +137,7 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
             console.log("clear");
         }
         this._touchDrag = false;
-        e.stopPropagation();
+        te.stopPropagation();
 
 
         // if (e.targetTouches.length === 0) {
@@ -126,11 +147,12 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
         if (this.prevPoints.size === 0) {
             this.cleanUpInteractions();
         }
+        e.stopPropagation();
     }
 
     cleanUpInteractions = (): void => {
-        document.removeEventListener("touchmove", this.onTouch);
-        document.removeEventListener("touchend", this.onTouchEnd);
+        this.removeMoveListeners();
+        this.removeEndListeners();
     }
 
     handle1PointerMove = (e: TouchEvent): any => {
@@ -144,23 +166,43 @@ export abstract class Touchable<T = {}> extends React.Component<T> {
     }
 
     handle1PointerDown = (e: React.TouchEvent): any => {
-        document.removeEventListener("touchmove", this.onTouch);
-        document.addEventListener("touchmove", this.onTouch);
-        document.removeEventListener("touchend", this.onTouchEnd);
-        document.addEventListener("touchend", this.onTouchEnd);
+        this.removeMoveListeners();
+        this.addMoveListeners();
+        this.removeEndListeners();
+        this.addEndListeners();
     }
 
     handle2PointersDown = (e: React.TouchEvent): any => {
-        document.removeEventListener("touchmove", this.onTouch);
-        document.addEventListener("touchmove", this.onTouch);
-        document.removeEventListener("touchend", this.onTouchEnd);
-        document.addEventListener("touchend", this.onTouchEnd);
+        this.removeMoveListeners();
+        this.addMoveListeners();
+        this.removeEndListeners();
+        this.addEndListeners();
     }
 
     handle1PointerHoldStart = (e: React.TouchEvent): any => {
         e.stopPropagation();
         e.preventDefault();
-        document.removeEventListener("touchmove", this.onTouch);
+        this.removeMoveListeners();
+    }
+
+    addMoveListeners = () => {
+        const handler = (e: Event) => this.onTouch(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
+        document.addEventListener("dashOnTouchMove", handler);
+        this.moveDisposer = () => document.removeEventListener("dashOnTouchMove", handler);
+    }
+
+    removeMoveListeners = () => {
+        this.moveDisposer && this.moveDisposer();
+    }
+
+    addEndListeners = () => {
+        const handler = (e: Event) => this.onTouchEnd(e, (e as CustomEvent<InteractionUtils.MultiTouchEvent<TouchEvent>>).detail);
+        document.addEventListener("dashOnTouchEnd", handler);
+        this.endDisposer = () => document.removeEventListener("dashOnTouchEnd", handler);
+    }
+
+    removeEndListeners = () => {
+        this.endDisposer && this.endDisposer();
     }
 
     handleHandDown = (e: React.TouchEvent) => {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 992820fc7..b8423af20 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -153,7 +153,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     createRef = (ele: HTMLDivElement | null) => {
         this._masonryGridRef = ele;
-        this.createDropAndGestureTarget(ele!); //so the whole grid is the drop target?
+        this.createDashEventsTarget(ele!); //so the whole grid is the drop target?
     }
 
     overlays = (doc: Doc) => {
@@ -309,7 +309,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             docList={docList}
             parent={this}
             type={type}
-            createDropTarget={this.createDropAndGestureTarget}
+            createDropTarget={this.createDashEventsTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
         />;
     }
@@ -342,7 +342,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             docList={docList}
             parent={this}
             type={type}
-            createDropTarget={this.createDropAndGestureTarget}
+            createDropTarget={this.createDashEventsTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
             setDocHeight={this.setDocHeight}
         />;
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 73dc7edc6..4133956fc 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -24,6 +24,7 @@ import { GooglePhotos } from "../../apis/google_docs/GooglePhotosClientUtils";
 import { ImageUtils } from "../../util/Import & Export/ImageUtils";
 import { Networking } from "../../Network";
 import { GestureUtils } from "../../../pen-gestures/GestureUtils";
+import { InteractionUtils } from "../../util/InteractionUtils";
 
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc) => boolean;
@@ -49,17 +50,20 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
     class CollectionSubView extends DocComponent<SubCollectionViewProps, T>(schemaCtor) {
         private dropDisposer?: DragManager.DragDropDisposer;
         private gestureDisposer?: GestureUtils.GestureEventDisposer;
+        protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
         private _childLayoutDisposer?: IReactionDisposer;
-        protected createDropAndGestureTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+        protected createDashEventsTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
             this.dropDisposer && this.dropDisposer();
             this.gestureDisposer && this.gestureDisposer();
+            this.multiTouchDisposer && this.multiTouchDisposer();
             if (ele) {
                 this.dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
                 this.gestureDisposer = GestureUtils.MakeGestureTarget(ele, this.onGesture.bind(this));
+                this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(ele, this.onTouchStart.bind(this));
             }
         }
         protected CreateDropTarget(ele: HTMLDivElement) { //used in schema view
-            this.createDropAndGestureTarget(ele);
+            this.createDashEventsTarget(ele);
         }
 
         componentDidMount() {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 84945c6e6..3894e9d63 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -326,29 +326,30 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     @action
     handle1PointerDown = (e: React.TouchEvent) => {
-        const pt = e.targetTouches.item(0);
-        if (pt) {
-            this._hitCluster = this.props.Document.useCluster ? this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)) !== -1 : false;
-            if (!e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) {
-                document.removeEventListener("touchmove", this.onTouch);
-                document.addEventListener("touchmove", this.onTouch);
-                document.removeEventListener("touchend", this.onTouchEnd);
-                document.addEventListener("touchend", this.onTouchEnd);
-                // if (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen) {
-                //     e.stopPropagation();
-                //     e.preventDefault();
-                //     const point = this.getTransform().transformPoint(pt.pageX, pt.pageY);
-                //     this._points.push({ X: point[0], Y: point[1] });
-                // }
-                if (InkingControl.Instance.selectedTool === InkTool.None) {
-                    this._lastX = pt.pageX;
-                    this._lastY = pt.pageY;
-                    e.stopPropagation();
-                    e.preventDefault();
-                }
-                else {
-                    e.stopPropagation();
-                    e.preventDefault();
+        if (!e.nativeEvent.cancelBubble) {
+            // const myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true);
+            const pt = e.changedTouches.item(0);
+            if (pt) {
+                this._hitCluster = this.props.Document.useCluster ? this.pickCluster(this.getTransform().transformPoint(pt.clientX, pt.clientY)) !== -1 : false;
+                if (!e.shiftKey && !e.altKey && !e.ctrlKey && this.props.active(true)) {
+                    this.removeMoveListeners();
+                    this.addMoveListeners();
+                    this.removeEndListeners();
+                    this.addEndListeners();
+                    // if (InkingControl.Instance.selectedTool === InkTool.Highlighter || InkingControl.Instance.selectedTool === InkTool.Pen) {
+                    //     e.stopPropagation();
+                    //     e.preventDefault();
+                    //     const point = this.getTransform().transformPoint(pt.pageX, pt.pageY);
+                    //     this._points.push({ X: point[0], Y: point[1] });
+                    // }
+                    if (InkingControl.Instance.selectedTool === InkTool.None) {
+                        this._lastX = pt.pageX;
+                        this._lastY = pt.pageY;
+                        e.preventDefault();
+                    }
+                    else {
+                        e.preventDefault();
+                    }
                 }
             }
         }
@@ -395,8 +396,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
-        document.removeEventListener("touchmove", this.onTouch);
-        document.removeEventListener("touchend", this.onTouchEnd);
+        this.removeMoveListeners();
+        this.removeEndListeners();
     }
 
     @action
@@ -482,7 +483,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     this.pan(pt);
                 }
             }
-            e.stopPropagation();
+            // e.stopPropagation();
             e.preventDefault();
         }
     }
@@ -527,7 +528,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     }
                 }
             }
-            e.stopPropagation();
+            // e.stopPropagation();
             e.preventDefault();
         }
     }
@@ -535,18 +536,21 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @action
     handle2PointersDown = (e: React.TouchEvent) => {
         if (!e.nativeEvent.cancelBubble && this.props.active(true)) {
-            const pt1: React.Touch | null = e.targetTouches.item(0);
-            const pt2: React.Touch | null = e.targetTouches.item(1);
-            if (!pt1 || !pt2) return;
+            // const pt1: React.Touch | null = e.targetTouches.item(0);
+            // const pt2: React.Touch | null = e.targetTouches.item(1);
+            // // if (!pt1 || !pt2) return;
+            const myTouches = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true);
+            const pt1 = myTouches[0];
+            const pt2 = myTouches[1];
 
             const centerX = Math.min(pt1.clientX, pt2.clientX) + Math.abs(pt2.clientX - pt1.clientX) / 2;
             const centerY = Math.min(pt1.clientY, pt2.clientY) + Math.abs(pt2.clientY - pt1.clientY) / 2;
             this._lastX = centerX;
             this._lastY = centerY;
-            document.removeEventListener("touchmove", this.onTouch);
-            document.addEventListener("touchmove", this.onTouch);
-            document.removeEventListener("touchend", this.onTouchEnd);
-            document.addEventListener("touchend", this.onTouchEnd);
+            this.removeMoveListeners();
+            this.addMoveListeners();
+            this.removeEndListeners();
+            this.addEndListeners();
             e.stopPropagation();
         }
     }
@@ -554,8 +558,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     cleanUpInteractions = () => {
         document.removeEventListener("pointermove", this.onPointerMove);
         document.removeEventListener("pointerup", this.onPointerUp);
-        document.removeEventListener("touchmove", this.onTouch);
-        document.removeEventListener("touchend", this.onTouchEnd);
+        this.removeMoveListeners();
+        this.removeEndListeners();
     }
 
     @action
@@ -989,9 +993,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // otherwise, they are stored in fieldKey.  All annotations to this document are stored in the extension document
         if (!this.extensionDoc) return (null);
         // let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
-        return <div className={"collectionfreeformview-container"} ref={this.createDropAndGestureTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+        return <div className={"collectionfreeformview-container"} ref={this.createDashEventsTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
             style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
-            onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
+            onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu}>
             {!this.Document.LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2e0ae09ba..b33bebe7d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -103,6 +103,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     private _gestureEventDisposer?: GestureUtils.GestureEventDisposer;
     private _titleRef = React.createRef<EditableView>();
 
+    protected multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
+
     public get displayName() { return "DocumentView(" + this.props.Document.title + ")"; } // this makes mobx trace() statements more descriptive
     public get ContentDiv() { return this._mainCont.current; }
     @computed get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
@@ -177,6 +179,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     componentDidMount() {
         this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
         this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
+        this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
 
         !this.props.dontRegisterView && DocumentManager.Instance.DocumentViews.push(this);
     }
@@ -184,7 +187,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @action
     componentDidUpdate() {
         this._dropDisposer && this._dropDisposer();
+        this._gestureEventDisposer && this._gestureEventDisposer();
+        this.multiTouchDisposer && this.multiTouchDisposer();
         this._mainCont.current && (this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this)));
+        this._mainCont.current && (this._gestureEventDisposer = GestureUtils.MakeGestureTarget(this._mainCont.current, this.onGesture.bind(this)));
+        this._mainCont.current && (this.multiTouchDisposer = InteractionUtils.MakeMultiTouchTarget(this._mainCont.current, this.onTouchStart.bind(this)));
     }
 
     @action
@@ -319,25 +326,24 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 }
             }
             if ((this.active || this.Document.onDragStart || this.Document.onClick) && !e.ctrlKey && !this.Document.lockedPosition && !this.Document.inOverlay) e.stopPropagation();
-            document.removeEventListener("touchmove", this.onTouch);
-            document.addEventListener("touchmove", this.onTouch);
-            document.removeEventListener("touchend", this.onTouchEnd);
-            document.addEventListener("touchend", this.onTouchEnd);
-            if ((e.nativeEvent as any).formattedHandled) e.stopPropagation();
+            this.removeMoveListeners();
+            this.addMoveListeners();
+            this.removeEndListeners();
+            this.addEndListeners();
+            e.stopPropagation();
         }
     }
 
     handle1PointerMove = (e: TouchEvent) => {
         if ((e as any).formattedHandled) { e.stopPropagation; return; }
         if (e.cancelBubble && this.active) {
-            document.removeEventListener("touchmove", this.onTouch);
+            this.removeMoveListeners();
         }
         else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.Document.onDragStart || this.Document.onClick) && !this.Document.lockedPosition && !this.Document.inOverlay) {
             const touch = InteractionUtils.GetMyTargetTouches(e, this.prevPoints, true)[0];
             if (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3) {
                 if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick)) {
-                    document.removeEventListener("touchmove", this.onTouch);
-                    document.removeEventListener("touchend", this.onTouchEnd);
+                    this.cleanUpInteractions();
                     this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
                 }
             }
@@ -352,10 +358,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             e.preventDefault();
 
-            document.removeEventListener("touchmove", this.onTouch);
-            document.addEventListener("touchmove", this.onTouch);
-            document.removeEventListener("touchend", this.onTouchEnd);
-            document.addEventListener("touchend", this.onTouchEnd);
+            this.removeMoveListeners();
+            this.addMoveListeners();
+            this.removeEndListeners();
+            this.addEndListeners();
         }
     }
 
@@ -970,7 +976,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 width: animwidth,
                 height: animheight,
                 opacity: this.Document.opacity
-            }} onTouchStart={this.onTouchStart}>
+            }}>
             {this.innards}
         </div>;
     }
diff --git a/src/pen-gestures/GestureUtils.ts b/src/pen-gestures/GestureUtils.ts
index 062604458..4b5ad6684 100644
--- a/src/pen-gestures/GestureUtils.ts
+++ b/src/pen-gestures/GestureUtils.ts
@@ -31,7 +31,7 @@ export namespace GestureUtils {
         element.addEventListener("dashOnGesture", handler);
         return () => {
             element.removeEventListener("dashOnGesture", handler);
-        }
+        };
     }
 
     export enum Gestures {
-- 
cgit v1.2.3-70-g09d2


From 8212288108c3acfd129e45b9f496f0606a8d2848 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 15 Jan 2020 17:17:35 -0500
Subject: changed freeformdocument to use contentfittingviews if specified with
 FitToBox.   fixed bugs with contentfittingviews & titles.

---
 src/Utils.ts                                          |  2 +-
 src/client/views/Templates.tsx                        | 11 ++++++++++-
 .../views/collections/CollectionStackingView.tsx      |  4 ++--
 .../collectionFreeForm/CollectionFreeFormView.tsx     |  8 ++++++--
 .../views/nodes/CollectionFreeFormDocumentView.tsx    | 19 ++++++++++---------
 src/client/views/nodes/DocumentView.scss              | 13 ++++++++++++-
 src/client/views/nodes/DocumentView.tsx               | 13 +++++++------
 src/client/views/nodes/FormattedTextBox.tsx           |  2 +-
 src/new_fields/Doc.ts                                 |  2 +-
 src/new_fields/documentSchemas.ts                     |  6 +++++-
 10 files changed, 55 insertions(+), 25 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index f50655f6c..7bf05a6fc 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -337,7 +337,7 @@ export function aggregateBounds(boundsList: { x: number, y: number, width: numbe
             r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b)
         };
     }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: -Number.MAX_VALUE, b: -Number.MAX_VALUE });
-    return { x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y, r: bounds.r !== -Number.MAX_VALUE ? bounds.r + 2 * xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + 2 * ypad : bounds.b };
+    return { x: bounds.x !== Number.MAX_VALUE ? bounds.x - xpad : bounds.x, y: bounds.y !== Number.MAX_VALUE ? bounds.y - ypad : bounds.y, r: bounds.r !== -Number.MAX_VALUE ? bounds.r + xpad : bounds.r, b: bounds.b !== -Number.MAX_VALUE ? bounds.b + ypad : bounds.b };
 }
 export function intersectRect(r1: { left: number, top: number, width: number, height: number },
     r2: { left: number, top: number, width: number, height: number }) {
diff --git a/src/client/views/Templates.tsx b/src/client/views/Templates.tsx
index ef78b60d4..8af8a6280 100644
--- a/src/client/views/Templates.tsx
+++ b/src/client/views/Templates.tsx
@@ -56,8 +56,17 @@ export namespace Templates {
                 <div style="width:100%;overflow:auto">{layout}</div>
             </div>
         </div>` );
+    export const TitleHover = new Template("TitleHover", TemplatePosition.InnerTop,
+        `<div>
+            <div style="height:25px; width:100%; background-color: rgba(0, 0, 0, .4); color: white; z-index: 100">
+                <span style="text-align:center;width:100%;font-size:20px;position:absolute;overflow:hidden;white-space:nowrap;text-overflow:ellipsis">{props.Document.title}</span>
+            </div>
+            <div style="height:calc(100% - 25px);">
+                <div style="width:100%;overflow:auto">{layout}</div>
+            </div>
+        </div>` );
 
-    export const TemplateList: Template[] = [Title, Caption];
+    export const TemplateList: Template[] = [Title, TitleHover, Caption];
 
     export function sortTemplates(a: Template, b: Template) {
         if (a.Position < b.Position) { return -1; }
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 3ab0326e2..886a9c870 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -41,7 +41,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized).map(d => (Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d).layout as Doc) || d); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
-    @computed get yMargin() { return Math.max(this.props.Document.showTitle ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
+    @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
     @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
@@ -152,7 +152,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
 
     overlays = (doc: Doc) => {
-        return doc.type === DocumentType.IMG || doc.type === DocumentType.VID ? { title: StrCast(this.props.Document.showTitles), caption: StrCast(this.props.Document.showCaptions) } : {};
+        return doc.type === DocumentType.IMG || doc.type === DocumentType.VID ? { title: StrCast(this.props.Document.showTitles), titleHover: StrCast(this.props.Document.showTitleHovers), caption: StrCast(this.props.Document.showCaptions) } : {};
     }
 
     @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 29f9ccfcd..7985e541f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -56,6 +56,8 @@ export const panZoomSchema = createSchema({
     useClusters: "boolean",
     isRuleProvider: "boolean",
     fitToBox: "boolean",
+    xPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
+    yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     panTransformType: "string",
     scrollHeight: "number",
     fitX: "number",
@@ -802,9 +804,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
         this.childLayoutPairs.filter((pair, i) => this.isCurrent(pair.layout)).forEach(pair =>
             computedElementData.elements.push({
-                ele: <CollectionFreeFormDocumentView key={pair.layout[Id]} dataProvider={this.childDataProvider}
+                ele: <CollectionFreeFormDocumentView key={pair.layout[Id]}  {...this.getChildDocumentViewProps(pair.layout, pair.data)}
+                    dataProvider={this.childDataProvider}
                     ruleProvider={this.Document.isRuleProvider ? this.props.Document : this.props.ruleProvider}
-                    jitterRotation={NumCast(this.props.Document.jitterRotation)} {...this.getChildDocumentViewProps(pair.layout, pair.data)} />,
+                    jitterRotation={NumCast(this.props.Document.jitterRotation)}
+                    fitToBox={this.props.fitToBox || this.Document.freeformLayoutEngine === "pivot"} />,
                 bounds: this.childDataProvider(pair.layout)
             }));
 
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index f79496ab7..614a68e7a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -11,6 +11,8 @@ import { DocumentView, DocumentViewProps } from "./DocumentView";
 import React = require("react");
 import { PositionDocument } from "../../../new_fields/documentSchemas";
 import { TraceMobx } from "../../../new_fields/util";
+import { returnFalse } from "../../../Utils";
+import { ContentFittingDocumentView } from "./ContentFittingDocumentView";
 
 export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     dataProvider?: (doc: Doc) => { x: number, y: number, width: number, height: number, z: number, transition?: string } | undefined;
@@ -20,6 +22,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
     height?: number;
     jitterRotation: number;
     transition?: string;
+    fitToBox?: boolean;
 }
 
 @observer
@@ -83,8 +86,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
 
     @observable _animPos: number[] | undefined = undefined;
 
-    finalPanelWidth = () => this.dataProvider ? this.dataProvider.width : this.panelWidth();
-    finalPanelHeight = () => this.dataProvider ? this.dataProvider.height : this.panelHeight();
+    finalPanelWidth = () => (this.dataProvider ? this.dataProvider.width : this.panelWidth());
+    finalPanelHeight = () => (this.dataProvider ? this.dataProvider.height : this.panelHeight());
 
     render() {
         TraceMobx();
@@ -104,24 +107,22 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
                 zIndex: this.Document.zIndex || 0,
             }} >
 
-            <DocumentView {...this.props}
+
+            {!this.props.fitToBox ? <DocumentView {...this.props}
                 dragDivName={"collectionFreeFormDocumentView-container"}
                 ContentScaling={this.contentScaling}
                 ScreenToLocalTransform={this.getTransform}
                 backgroundColor={this.clusterColorFunc}
                 PanelWidth={this.finalPanelWidth}
                 PanelHeight={this.finalPanelHeight}
-            />
-            {/* <ContentFittingDocumentView {...this.props}
-                //dragDivName={"collectionFreeFormDocumentView-container"}
-                //ContentScaling={this.contentScaling}
+            /> : <ContentFittingDocumentView {...this.props}
+                DataDocument={this.props.DataDoc}
                 getTransform={this.getTransform}
                 active={returnFalse}
                 focus={(doc: Doc) => this.props.focus(doc, false)}
-                // backgroundColor={this.clusterColorFunc}
                 PanelWidth={this.finalPanelWidth}
                 PanelHeight={this.finalPanelHeight}
-            /> */}
+                />}
         </div>;
     }
 }
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index f44c6dd3b..2ce56c73d 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -55,7 +55,7 @@
             position: absolute;
         }
 
-        .documentView-titleWrapper {
+        .documentView-titleWrapper, .documentView-titleWrapper-hover {
             overflow: hidden;
             color: white;
             transform-origin: top left;
@@ -68,6 +68,9 @@
             text-overflow: ellipsis;
             white-space: pre;
         }
+        .documentView-titleWrapper-hover {
+            display:none;
+        }
 
         .documentView-searchHighlight {
             position: absolute;
@@ -85,4 +88,12 @@
         }
     }
 
+}
+
+.documentView-node:hover, .documentView-node-topmost:hover {
+    > .documentView-styleWrapper {
+        > .documentView-titleWrapper-hover {
+            display:inline-block;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8f3fa4530..b2c2ccff5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -29,7 +29,6 @@ import { CollectionDockingView } from "../collections/CollectionDockingView";
 import { CollectionView } from "../collections/CollectionView";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
-import { DictationOverlay } from '../DictationOverlay';
 import { DocComponent } from "../DocComponent";
 import { EditableView } from '../EditableView';
 import { OverlayView } from '../OverlayView';
@@ -64,7 +63,7 @@ export interface DocumentViewProps {
     moveDocument?: (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     renderDepth: number;
-    showOverlays?: (doc: Doc) => { title?: string, caption?: string };
+    showOverlays?: (doc: Doc) => { title?: string, titleHover?: string, caption?: string };
     ContentScaling: () => number;
     ruleProvider: Doc | undefined;
     PanelWidth: () => number;
@@ -741,7 +740,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     chromeHeight = () => {
         const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
         const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.layoutDoc.showTitle);
-        return (showTitle ? 25 : 0) + 1;
+        const showTitleHover = showOverlays && "titleHover" in showOverlays ? showOverlays.titleHover : StrCast(this.layoutDoc.showTitleHover);
+        return (showTitle && !showTitleHover ? 0 : 0) + 1;
     }
 
     @computed get finalLayoutKey() { return this.props.layoutKey || "layout"; }
@@ -751,6 +751,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         return (<DocumentContentsView ContainingCollectionView={this.props.ContainingCollectionView}
             ContainingCollectionDoc={this.props.ContainingCollectionDoc}
             Document={this.props.Document}
+            DataDoc={this.props.DataDoc}
             fitToBox={this.props.fitToBox}
             LibraryPath={this.props.LibraryPath}
             addDocument={this.props.addDocument}
@@ -777,8 +778,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             isSelected={this.isSelected}
             select={this.select}
             onClick={this.onClickHandler}
-            layoutKey={this.finalLayoutKey}
-            DataDoc={this.props.DataDoc} />);
+            layoutKey={this.finalLayoutKey} />);
     }
     linkEndpoint = (linkDoc: Doc) => Doc.LinkEndpoint(linkDoc, this.props.Document);
 
@@ -795,6 +795,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         TraceMobx();
         const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
         const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.getLayoutPropStr("showTitle"));
+        const showTitleHover = showOverlays && "titleHover" in showOverlays ? showOverlays.titleHover : StrCast(this.getLayoutPropStr("showTitleHover"));
         const showCaption = showOverlays && "caption" in showOverlays ? showOverlays.caption : this.getLayoutPropStr("showCaption");
         const showTextTitle = showTitle && StrCast(this.layoutDoc.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined;
         const searchHighlight = (!this.Document.searchFields ? (null) :
@@ -810,7 +811,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 />
             </div>);
         const titleView = (!showTitle ? (null) :
-            <div className="documentView-titleWrapper" style={{
+            <div className={`documentView-titleWrapper${showTitleHover ? "-hover" : ""}`} style={{
                 position: showTextTitle ? "relative" : "absolute",
                 pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
             }}>
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 8b5c24878..60842bcb0 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -940,7 +940,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             }
             if (!node && this.ProseRef) {
                 const lastNode = this.ProseRef.children[this.ProseRef.children.length - 1].children[this.ProseRef.children[this.ProseRef.children.length - 1].children.length - 1]; // get the last prosemirror div
-                if (e.clientY > lastNode.getBoundingClientRect().bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document
+                if (e.clientY > lastNode?.getBoundingClientRect().bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document
                     this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, this._editorView!.state.doc.content.size)));
                 }
             }
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 26acfa9c3..e0ab5d97c 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -455,7 +455,7 @@ export namespace Doc {
         if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
             const extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
             layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined);
-            layoutDoc && (layoutDoc.resolvedDataDoc = resolvedDataDoc);
+            setTimeout(() => layoutDoc && (layoutDoc.resolvedDataDoc = resolvedDataDoc), 0);
         } else layoutDoc = childDocLayout;
         return { layout: layoutDoc, data: resolvedDataDoc };
     }
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index 21e69fbed..909fdc6c3 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -41,7 +41,8 @@ export const documentSchema = createSchema({
     searchFields: "string",     // the search fields to display when this document matches a search in its metadata
     heading: "number",          // the logical layout 'heading' of this document (used by rule provider to stylize h1 header elements, from h2, etc)
     showCaption: "string",      // whether editable caption text is overlayed at the bottom of the document 
-    showTitle: "string",        // whether an editable title banner is displayed at tht top of the document
+    showTitle: "string",        // the fieldkey whose contents should be displayed at the top of the document
+    showTitleHover: "string",   // the showTitle should be shown only on hover
     isButton: "boolean",        // whether document functions as a button (overiding native interactions of its content)    
     ignoreClick: "boolean",     // whether documents ignores input clicks (but does not ignore manipulation and other events) 
     isAnimating: "string",      // whether the document is in the midst of animating between two layouts (used by icons to de/iconify documents).  value is undefined|"min"|"max"
@@ -49,6 +50,9 @@ export const documentSchema = createSchema({
     scrollToLinkID: "string",   // id of link being traversed. allows this doc to scroll/highlight/etc its link anchor. scrollToLinkID should be set to undefined by this doc after it sets up its scroll,etc.
     strokeWidth: "number",
     fontSize: "string",
+    fitToBox: "boolean",        // whether freeform view contents should be zoomed/panned to fill the area of the document view
+    xPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
+    yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     LODarea: "number",          // area (width*height) where CollectionFreeFormViews switch from a label to rendering contents
     LODdisable: "boolean",      // whether to disbale LOD switching for CollectionFreeFormViews
 });
-- 
cgit v1.2.3-70-g09d2


From fcd9313158f8c131cf5a124880c46ca7b20a1b25 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 16 Jan 2020 11:43:38 -0500
Subject: better fix for sidebar / stacking view sizing

---
 src/client/views/MainView.scss                          | 8 --------
 src/client/views/collections/CollectionStackingView.tsx | 2 +-
 2 files changed, 1 insertion(+), 9 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index c7fc6096a..4c8c95529 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -5,9 +5,6 @@
 .mainView-tabButtons {
     position: relative;
     width: 100%;
-    .documentView-node-topmost {
-        height: 200% !important;
-    }
 }
 
 .mainContent-div {
@@ -16,11 +13,6 @@
     height:100%;
 }
 
-.mainView-contentArea {
-    .documentView-node-topmost {
-        height: 200% !important;
-    }
-}
 // add nodes menu. Note that the + button is actually an input label, not an actual button.
 .mainView-docButtons {
     position: absolute;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 886a9c870..ca792c134 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -396,7 +396,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     ref={this.createRef}
                     style={{
                         transform: `scale(${Math.min(1, this.props.PanelHeight() / this.layoutDoc[HeightSym]())})`,
-                        height: `${100 * 1 / Math.min(this.props.PanelWidth() / this.layoutDoc[WidthSym](), this.props.PanelHeight() / this.layoutDoc[HeightSym]())}%`,
+                        height: `${Math.max(100, 100 * 1 / Math.min(this.props.PanelWidth() / this.layoutDoc[WidthSym](), this.props.PanelHeight() / this.layoutDoc[HeightSym]()))}%`,
                         transformOrigin: "top"
                     }}
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
-- 
cgit v1.2.3-70-g09d2


From f970dd586c0914847b5a59951f586dad93a2cf04 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 22 Jan 2020 22:04:46 -0500
Subject: streamling templates.

---
 src/client/documents/Documents.ts                  |  2 +-
 src/client/util/DropConverter.ts                   |  4 +-
 src/client/views/DocComponent.tsx                  |  4 +-
 src/client/views/DocumentDecorations.tsx           |  2 +-
 src/client/views/InkingControl.tsx                 |  2 +-
 .../views/collections/CollectionStackingView.tsx   |  2 +-
 src/client/views/collections/CollectionSubView.tsx |  8 +--
 .../views/collections/CollectionTreeView.tsx       |  6 +--
 .../collectionFreeForm/CollectionFreeFormView.tsx  |  2 +-
 src/client/views/nodes/ButtonBox.tsx               |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  8 +--
 src/client/views/nodes/FormattedTextBox.tsx        |  2 +-
 src/new_fields/Doc.ts                              | 63 +++++++++++-----------
 src/new_fields/documentSchemas.ts                  |  2 +-
 14 files changed, 55 insertions(+), 54 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index e86ed52f3..6132f787b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -76,7 +76,7 @@ export interface DocumentOptions {
     preventTreeViewOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expande/collapse state to be independent of other views of the same document in the tree view
     layout?: string | Doc;
     hideHeadings?: boolean; // whether stacking view column headings should be hidden
-    isTemplateField?: boolean;
+    isTemplateForField?: string; // the field key for which the containing document is a rendering template
     isTemplateDoc?: boolean;
     templates?: List<string>;
     viewType?: number;
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 3e2cc6a2e..66caf52cb 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -8,7 +8,7 @@ import { Docs } from "../documents/Documents";
 import { ScriptField } from "../../new_fields/ScriptField";
 
 export function makeTemplate(doc: Doc): boolean {
-    const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+    const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
     const layout = StrCast(layoutDoc.layout).match(/fieldKey={'[^']*'}/)![0];
     const fieldKey = layout.replace("fieldKey={'", "").replace(/'}$/, "");
     const docs = DocListCast(layoutDoc[fieldKey]);
@@ -28,7 +28,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
         let dbox = doc;
         // bcz: isButtonBar is intended to allow a collection of linear buttons to be dropped and nested into another collection of buttons... it's not being used yet, and isn't very elegant
         if (!doc.onDragStart && !doc.onClick && !doc.isButtonBar) {
-            const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateField ? doc.layout : doc;
+            const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
             if (layoutDoc.type === DocumentType.COL) {
                 layoutDoc.isTemplateDoc = makeTemplate(layoutDoc);
             } else {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 4dbf26956..1ffbd80ca 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -34,7 +34,7 @@ export function DocExtendableComponent<P extends DocExtendableProps, T>(schemaCt
         //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
         @computed get Document(): T { return schemaCtor(this.props.Document); }
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
-        @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
+        @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
         @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
         active = (outsideReaction?: boolean) => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0);//  && !InkingControl.Instance.selectedTool;  // bcz: inking state shouldn't affect static tools 
     }
@@ -58,7 +58,7 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         //TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
         @computed get Document(): T { return schemaCtor(this.props.Document); }
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
-        @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
+        @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
         @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
         @computed get extensionDocSync() { return Doc.fieldExtensionDocSync(this.dataDoc, this.props.fieldKey); }
         @computed get annotationsKey() { return "annotations"; }
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 32fea15fb..322536b7e 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -369,7 +369,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`);
             usingRule = usingRule || (ruleProvider && heading ? true : false);
         });
-        !usingRule && SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplateField ? dv.props.Document : Doc.GetProto(dv.props.Document)).
+        !usingRule && SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplateForField ? dv.props.Document : Doc.GetProto(dv.props.Document)).
             map(d => d.borderRounding = `${Math.min(100, dist)}%`);
         e.stopPropagation();
         e.preventDefault();
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index be07a9024..853d81a68 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -44,7 +44,7 @@ export class InkingControl {
             const oldColors = selected.map(view => {
                 const targetDoc = view.props.Document.dragFactory instanceof Doc ? view.props.Document.dragFactory :
                     view.props.Document.layout instanceof Doc ? view.props.Document.layout :
-                        view.props.Document.isTemplateField ? view.props.Document : Doc.GetProto(view.props.Document);
+                        view.props.Document.isTemplateForField ? view.props.Document : Doc.GetProto(view.props.Document);
                 const sel = window.getSelection();
                 if (StrCast(targetDoc.layout).indexOf("FormattedTextBox") !== -1 && (!sel || sel.toString() !== "")) {
                     targetDoc.color = this._selectedColor;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7fe42386a..b2e4b9d90 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -39,7 +39,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
-    @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized).map(d => (Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d).layout as Doc) || d); }
+    @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized).map(d => (Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, d).layout as Doc) || d); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 9357b0507..6c4f940b6 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -73,7 +73,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                         this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), "layoutFromParent"));
                     }
                     else if (!(args[1] instanceof Promise)) {
-                        this.childDocs.filter(d => !d.isTemplateField).map(async doc => doc.layoutKey === "layoutFromParent" && (doc.layoutKey = "layout"));
+                        this.childDocs.filter(d => !d.isTemplateForField).map(async doc => doc.layoutKey === "layoutFromParent" && (doc.layoutKey = "layout"));
                     }
                 });
 
@@ -82,7 +82,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             this._childLayoutDisposer && this._childLayoutDisposer();
         }
 
-        @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc) : Doc.GetProto(this.props.Document); }
+        @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) : Doc.GetProto(this.props.Document); }
         @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
 
         // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc.
@@ -102,8 +102,8 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         }
 
         get childLayoutPairs(): { layout: Doc; data: Doc; }[] {
-            const { Document, DataDoc, fieldKey } = this.props;
-            const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, DataDoc, fieldKey, doc)).filter(pair => pair.layout);
+            const { Document, DataDoc } = this.props;
+            const validPairs = this.childDocs.map(doc => Doc.GetLayoutDataDocPair(Document, DataDoc, doc)).filter(pair => pair.layout);
             return validPairs.map(({ data, layout }) => ({ data: data!, layout: layout! })); // this mapping is a bit of a hack to coerce types
         }
         get childDocList() {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6b6fdff50..2c8c53f97 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -375,7 +375,7 @@ class TreeView extends React.Component<TreeViewProps> {
         if (this.props.onCheckedClick && this.props.document.type !== DocumentType.COL) {
             // this.props.document.treeViewChecked = this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check";
             ScriptCast(this.props.onCheckedClick).script.run({
-                this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document,
+                this: this.props.document.isTemplateForField && this.props.dataDoc ? this.props.dataDoc : this.props.document,
                 heading: this.props.containingCollection.title,
                 checked: this.props.document.treeViewChecked === "check" ? "x" : this.props.document.treeViewChecked === "x" ? undefined : "check",
                 containingTreeView: this.props.treeViewId,
@@ -519,7 +519,7 @@ class TreeView extends React.Component<TreeViewProps> {
 
         const rowWidth = () => panelWidth() - 20;
         return docs.map((child, i) => {
-            const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, key, child);
+            const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child);
             if (!pair.layout || pair.data instanceof Promise) {
                 return (null);
             }
@@ -646,7 +646,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                 ], { autoHeight: true, chromeStatus: "disabled", title: "detailed layout stack" });
                 detailedLayout.isTemplateDoc = makeTemplate(detailedLayout);
 
-                const cardLayout = ImageDocument(fallbackImg, { isTemplateDoc: true, isTemplateField: true }); // this acts like a template doc and a template field ... a little weird, but seems to work?
+                const cardLayout = ImageDocument(fallbackImg, { isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
                 cardLayout.proto!.layout = ImageBox.LayoutString("hero");
                 cardLayout.showTitle = "title";
                 cardLayout.showTitleHover = "titlehover";
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index a7e4fce4e..aa1559416 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -833,7 +833,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         this.Document.isRuleProvider && this.childLayoutPairs.map(pair =>
             // iterate over the children of a displayed document (or if the displayed document is a template, iterate over the children of that template)
             DocListCast(Doc.Layout(pair.layout).data).map(heading => {
-                const headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, heading);
+                const headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, heading);
                 const headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
                 if (headingLayout && NumCast(headingLayout.heading) > 0 && headingLayout.backgroundColor !== headingLayout.defaultBackgroundColor) {
                     Doc.GetProto(this.props.Document)["ruleColor_" + NumCast(headingLayout.heading)] = headingLayout.backgroundColor;
diff --git a/src/client/views/nodes/ButtonBox.tsx b/src/client/views/nodes/ButtonBox.tsx
index d29fe1711..ee48b47b7 100644
--- a/src/client/views/nodes/ButtonBox.tsx
+++ b/src/client/views/nodes/ButtonBox.tsx
@@ -36,7 +36,7 @@ export class ButtonBox extends DocComponent<FieldViewProps, ButtonDocument>(Butt
 
     @computed get dataDoc() {
         return this.props.DataDoc &&
-            (this.Document.isTemplateField || BoolCast(this.props.DataDoc.isTemplateField) ||
+            (this.Document.isTemplateForField || BoolCast(this.props.DataDoc.isTemplateForField) ||
                 this.props.DataDoc.layout === this.props.Document) ? this.props.DataDoc : Doc.GetProto(this.props.Document);
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 36f2e7a4d..b491acb8d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -268,7 +268,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 SelectionManager.DeselectAll();
                 Doc.UnBrushDoc(this.props.Document);
             } else if (this.onClickHandler && this.onClickHandler.script) {
-                this.onClickHandler.script.run({ this: this.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document, containingCollection: this.props.ContainingCollectionDoc }, console.log);
+                this.onClickHandler.script.run({ this: this.Document.isTemplateForField && this.props.DataDoc ? this.props.DataDoc : this.props.Document, containingCollection: this.props.ContainingCollectionDoc }, console.log);
             } else if (this.Document.type === DocumentType.BUTTON) {
                 ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY);
             } else if (this.props.Document.isButton === "Selector") {  // this should be moved to an OnClick script
@@ -438,7 +438,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     onPointerDown = (e: React.PointerEvent): void => {
         if (this.onPointerDownHandler && this.onPointerDownHandler.script) {
-            this.onPointerDownHandler.script.run({ this: this.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
+            this.onPointerDownHandler.script.run({ this: this.Document.isTemplateForField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
             document.removeEventListener("pointerup", this.onPointerUp);
             document.addEventListener("pointerup", this.onPointerUp);
             return;
@@ -495,7 +495,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     onPointerUp = (e: PointerEvent): void => {
         if (this.onPointerUpHandler && this.onPointerUpHandler.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) {
-            this.onPointerUpHandler.script.run({ this: this.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
+            this.onPointerUpHandler.script.run({ this: this.Document.isTemplateForField && this.props.DataDoc ? this.props.DataDoc : this.props.Document }, console.log);
             document.removeEventListener("pointerup", this.onPointerUp);
             return;
         }
@@ -996,7 +996,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 color: StrCast(this.Document.color),
                 outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
                 border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
-                boxShadow: this.props.Document.isTemplateField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
+                boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
                 background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
                 width: animwidth,
                 height: animheight,
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 1cd5cdcea..3814f02da 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1101,7 +1101,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 this.layoutDoc.limitHeight = undefined;
                 this.layoutDoc.autoHeight = false;
             }
-            const nh = this.Document.isTemplateField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
+            const nh = this.Document.isTemplateForField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
             const dh = NumCast(this.layoutDoc.height, 0);
             const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
             if (Math.abs(newHeight - dh) > 1) { // bcz: Argh!  without this, we get into a React crash if the same document is opened in a freeform view and in the treeview.  no idea why, but after dragging the freeform document, selecting it, and selecting text, it will compute to 1 pixel higher than the treeview which causes a cycle
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index e9f8e6429..669e7a72f 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -431,48 +431,49 @@ export namespace Doc {
 
     //
     // Determines whether the combination of the layoutDoc and dataDoc represents
-    // a template relationship.  If so, the layoutDoc will be expanded into a new
-    // document that inherits the properties of the original layout while allowing
-    // for individual layout properties to be overridden in the expanded layout.
+    // a template relationship :  there is a dataDoc and it doesn't match the layoutDoc an
+    // the lyouatDoc's layout is layout string (not a document) 
     //
     export function WillExpandTemplateLayout(layoutDoc: Doc, dataDoc?: Doc) {
-        return BoolCast(layoutDoc.isTemplateField) && dataDoc && layoutDoc !== dataDoc && !(layoutDoc[StrCast(layoutDoc.layoutKey, "layout")] instanceof Doc);
+        return layoutDoc.isTemplateForField && dataDoc && layoutDoc !== dataDoc && !(Doc.LayoutField(layoutDoc) instanceof Doc);
     }
 
     //
-    // Returns an expanded template layout for a target data document.
-    // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
-    // using the template layout doc's id as the field key.
-    // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
-    // saves it on the data doc indexed by the template layout's id
+    // Returns an expanded template layout for a target data document if there is a template relationship
+    // between the two. If so, the layoutDoc is expanded into a new document that inherits the properties 
+    // of the original layout while allowing for individual layout properties to be overridden in the expanded layout.
     //
     export function expandTemplateLayout(templateLayoutDoc: Doc, dataDoc?: Doc) {
         if (!WillExpandTemplateLayout(templateLayoutDoc, dataDoc) || !dataDoc) return templateLayoutDoc;
-        // if we have a data doc that doesn't match the layout, then we're rendering a template.
-        // ... which means we change the layout to be an expanded view of the template layout.  
-        // This allows the view override the template's properties and be referenceable as its own document.
 
+        const templateField = StrCast(templateLayoutDoc.isTemplateForField);  // the field that the template renders
+        const extensionDoc = fieldExtensionDoc(dataDoc, templateField); // an extension doc for the field that the template renders
+        // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
+        // using the template layout doc's id as the field key.
+        // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
+        // saves it on the data doc indexed by the template layout's id.
+        //
         const expandedLayoutFieldKey = "Layout[" + templateLayoutDoc[Id] + "]";
-        const expandedTemplateLayout = dataDoc[expandedLayoutFieldKey];
-        if (expandedTemplateLayout instanceof Doc) {
-            return expandedTemplateLayout;
-        }
-        if (expandedTemplateLayout === undefined) {
-            setTimeout(() => dataDoc[expandedLayoutFieldKey] === undefined &&
-                (dataDoc[expandedLayoutFieldKey] = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]")), 0);
+        const expandedTemplateLayout = extensionDoc?.[expandedLayoutFieldKey];
+        if (expandedTemplateLayout === undefined && extensionDoc) {
+            setTimeout(() => {
+                if (!extensionDoc[expandedLayoutFieldKey]) {
+                    const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
+                    extensionDoc[expandedLayoutFieldKey] = newLayoutDoc;
+                    newLayoutDoc.resolvedDataDoc = dataDoc;
+                }
+            }, 0);
         }
-        return undefined; // use the templateLayout when it's not a template or the expandedTemplate is pending.
+        return expandedTemplateLayout instanceof Doc ? expandedTemplateLayout : undefined; // layout is undefined if the expandedTemplate is pending.
     }
 
-    export function GetLayoutDataDocPair(doc: Doc, dataDoc: Doc | undefined, fieldKey: string, childDocLayout: Doc) {
-        let layoutDoc: Doc | undefined = childDocLayout;
-        const resolvedDataDoc = !doc.isTemplateField && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined;
-        if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
-            const extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
-            layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined);
-            setTimeout(async () => layoutDoc && (layoutDoc.resolvedDataDoc = await resolvedDataDoc), 0);
-        } else layoutDoc = childDocLayout;
-        return { layout: layoutDoc, data: resolvedDataDoc };
+    // returns the layout/data doc pair to render for the specified childDoc of a collection.
+    // The containerDoc is treated as a template if its containerDataDoc has a value.  If so, 
+    // the childDoc is treated as a layout description for some field of the container doc's data doc.
+    export function GetLayoutDataDocPair(containerDoc: Doc, containerDataDoc: Opt<Doc>, childDoc: Doc) {
+        const resolvedDataDoc = containerDoc.isTemplateForField || containerDataDoc === containerDoc || !containerDataDoc ?
+            undefined : Doc.GetDataDoc(containerDataDoc);
+        return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
     }
 
     //
@@ -483,6 +484,7 @@ export namespace Doc {
     // to store annotations, ink, and other data.
     //
     export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
+        if (!fieldKey) return undefined;
         const extension = doc[fieldKey + "_ext"];
         if (doc instanceof Doc && extension === undefined) {
             setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
@@ -616,8 +618,7 @@ export namespace Doc {
         const metadataFieldKey = StrCast(templateField.title).replace(/^-/, "");
 
         // update the original template to mark it as a template
-        templateField.templateField = metadataFieldKey;
-        templateField.isTemplateField = true;
+        templateField.isTemplateForField = metadataFieldKey;
         templateField.title = metadataFieldKey;
         // templateField.showTitle = suppressTitle ? undefined : "title";
 
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index 3683e5820..180c52b3d 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -26,7 +26,7 @@ export const documentSchema = createSchema({
     dragFactory: Doc,           // the document that serves as the "template" for the onDragStart script.  ie, to drag out copies of the dragFactory document.
     ignoreAspect: "boolean",    // whether aspect ratio should be ignored when laying out or manipulating the document
     autoHeight: "boolean",      // whether the height of the document should be computed automatically based on its contents
-    isTemplateField: "boolean", // whether this document acts as a template layout for describing how other documents should be displayed
+    isTemplateForField: "string",// when specifies a field key, then the containing document is a template that renders the specified field
     isBackground: "boolean",    // whether document is a background element and ignores input events (can only selet with marquee)
     type: "string",             // enumerated type of document
     treeViewOpen: "boolean",    //  flag denoting whether the documents sub-tree (contents) is visible or hidden
-- 
cgit v1.2.3-70-g09d2


From 0142f4e14cc8e291ee5acbae3cc4b81c95c4634a Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 23 Jan 2020 00:40:55 -0500
Subject: got rid of rule provider stuff.  fixed panning in freeform view with
 pivot layouts

---
 src/client/util/RichTextMenu.tsx                   | 20 ++---------
 src/client/util/RichTextRules.ts                   | 24 -------------
 src/client/util/RichTextSchema.tsx                 |  1 -
 src/client/views/DocumentDecorations.tsx           |  9 +----
 src/client/views/GestureOverlay.tsx                |  1 -
 src/client/views/InkingControl.tsx                 | 29 +--------------
 src/client/views/MainView.tsx                      |  4 ---
 src/client/views/OverlayView.tsx                   |  1 -
 src/client/views/Palette.tsx                       |  1 -
 .../views/collections/CollectionDockingView.tsx    |  1 -
 .../views/collections/CollectionLinearView.tsx     |  1 -
 .../views/collections/CollectionSchemaCells.tsx    |  1 -
 .../views/collections/CollectionSchemaView.tsx     |  1 -
 .../views/collections/CollectionStackingView.tsx   |  3 +-
 src/client/views/collections/CollectionSubView.tsx |  1 -
 .../views/collections/CollectionTreeView.tsx       |  3 --
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 42 +++++-----------------
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  4 +--
 .../views/nodes/ContentFittingDocumentView.tsx     |  2 --
 src/client/views/nodes/DocumentBox.tsx             |  1 -
 src/client/views/nodes/DocumentView.tsx            |  8 ++---
 src/client/views/nodes/FieldView.tsx               |  1 -
 src/client/views/nodes/FormattedTextBox.tsx        | 33 -----------------
 src/client/views/nodes/FormattedTextBoxComment.tsx |  1 -
 src/client/views/nodes/ImageBox.tsx                |  1 -
 src/client/views/nodes/KeyValuePair.tsx            |  1 -
 src/client/views/nodes/VideoBox.tsx                |  1 -
 src/client/views/nodes/WebBox.tsx                  |  1 -
 src/client/views/pdf/PDFViewer.tsx                 |  1 -
 .../views/presentationview/PresElementBox.tsx      |  1 -
 src/client/views/search/SearchItem.tsx             |  1 -
 src/mobile/MobileInterface.tsx                     |  1 -
 32 files changed, 16 insertions(+), 185 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx
index eb5c90654..e07efe056 100644
--- a/src/client/util/RichTextMenu.tsx
+++ b/src/client/util/RichTextMenu.tsx
@@ -367,27 +367,11 @@ export default class RichTextMenu extends AntimodeMenu {
     }
 
     changeFontSize = (mark: Mark, view: EditorView) => {
-        const size = mark.attrs.fontSize;
-        if (this.editorProps) {
-            const ruleProvider = this.editorProps.ruleProvider;
-            const heading = NumCast(this.editorProps.Document.heading);
-            if (ruleProvider && heading) {
-                ruleProvider["ruleSize_" + heading] = size;
-            }
-        }
-        this.setMark(view.state.schema.marks.pFontSize.create({ fontSize: size }), view.state, view.dispatch);
+        this.setMark(view.state.schema.marks.pFontSize.create({ fontSize: mark.attrs.fontSize }), view.state, view.dispatch);
     }
 
     changeFontFamily = (mark: Mark, view: EditorView) => {
-        const fontName = mark.attrs.family;
-        if (this.editorProps) {
-            const ruleProvider = this.editorProps.ruleProvider;
-            const heading = NumCast(this.editorProps.Document.heading);
-            if (ruleProvider && heading) {
-                ruleProvider["ruleFont_" + heading] = fontName;
-            }
-        }
-        this.setMark(view.state.schema.marks.pFontFamily.create({ family: fontName }), view.state, view.dispatch);
+        this.setMark(view.state.schema.marks.pFontFamily.create({ family: mark.attrs.family }), view.state, view.dispatch);
     }
 
     // TODO: remove doesn't work
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index e20abb04c..0ee9481f0 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -67,12 +67,6 @@ export const inpRules = {
             new RegExp(/^%([0-9]+)\s$/),
             (state, match, start, end) => {
                 const size = Number(match[1]);
-                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
-                if (ruleProvider && heading) {
-                    (Cast(FormattedTextBox.FocusedBox!.props.Document, Doc) as Doc).heading = size;
-                    return state.tr.deleteRange(start, end);
-                }
                 return state.tr.deleteRange(start, end).addStoredMark(schema.marks.pFontSize.create({ fontSize: size }));
             }),
 
@@ -175,12 +169,6 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
-                if (ruleProvider && heading) {
-                    ruleProvider["ruleAlign_" + heading] = "center";
-                    return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
-                }
                 const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "center" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
@@ -191,12 +179,6 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
-                if (ruleProvider && heading) {
-                    ruleProvider["ruleAlign_" + heading] = "left";
-                    return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
-                }
                 const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "left" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
@@ -207,12 +189,6 @@ export const inpRules = {
             (state, match, start, end) => {
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const sm = state.storedMarks || undefined;
-                const ruleProvider = FormattedTextBox.FocusedBox!.props.ruleProvider;
-                const heading = NumCast(FormattedTextBox.FocusedBox!.props.Document.heading);
-                if (ruleProvider && heading) {
-                    ruleProvider["ruleAlign_" + heading] = "right";
-                    return node ? state.tr.deleteRange(start, end).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
-                }
                 const replaced = node ? state.tr.replaceRangeWith(start, end, schema.nodes.paragraph.create({ align: "right" })).setStoredMarks([...node.marks, ...(sm ? sm : [])]) :
                     state.tr;
                 return replaced.setSelection(new TextSelection(replaced.doc.resolve(end - 2)));
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 5751c8c7e..fe7ab31a8 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -761,7 +761,6 @@ export class DashDocView {
                     fitToBox={BoolCast(dashDoc.fitToBox)}
                     addDocument={returnFalse}
                     removeDocument={removeDoc}
-                    ruleProvider={undefined}
                     ScreenToLocalTransform={this.getDocTransform}
                     addDocTab={self._textBox.props.addDocTab}
                     pinToPres={returnFalse}
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 322536b7e..e6a119d1f 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -362,14 +362,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     onRadiusMove = (e: PointerEvent): void => {
         let dist = Math.sqrt((e.clientX - this._radiusDown[0]) * (e.clientX - this._radiusDown[0]) + (e.clientY - this._radiusDown[1]) * (e.clientY - this._radiusDown[1]));
         dist = dist < 3 ? 0 : dist;
-        let usingRule = false;
-        SelectionManager.SelectedDocuments().map(dv => {
-            const ruleProvider = dv.props.ruleProvider;
-            const heading = NumCast(dv.props.Document.heading);
-            ruleProvider && heading && (Doc.GetProto(ruleProvider)["ruleRounding_" + heading] = `${Math.min(100, dist)}%`);
-            usingRule = usingRule || (ruleProvider && heading ? true : false);
-        });
-        !usingRule && SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplateForField ? dv.props.Document : Doc.GetProto(dv.props.Document)).
+        SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplateForField ? dv.props.Document : Doc.GetProto(dv.props.Document)).
             map(d => d.borderRounding = `${Math.min(100, dist)}%`);
         e.stopPropagation();
         e.preventDefault();
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 84d089b47..580c53a37 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -462,7 +462,6 @@ export default class GestureOverlay extends Touchable {
                 addDocTab={returnFalse}
                 pinToPres={emptyFunction}
                 onClick={undefined}
-                ruleProvider={undefined}
                 removeDocument={undefined}
                 ScreenToLocalTransform={() => new Transform(-(this._thumbX ?? 0), -(this._thumbY ?? 0) + this.height, 1)}
                 ContentScaling={returnOne}
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index ab53b76be..10d013865 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -55,34 +55,7 @@ export class InkingControl {
                 }
                 const oldColor = StrCast(targetDoc.backgroundColor);
                 let matchedColor = this._selectedColor;
-                const cvd = view.props.ContainingCollectionDoc;
-                let ruleProvider = view.props.ruleProvider;
-                // if (cvd) {
-                //     if (!cvd.colorPalette) {
-                //         const defaultPalette = ["rg(114,229,239)", "rgb(255,246,209)", "rgb(255,188,156)", "rgb(247,220,96)", "rgb(122,176,238)",
-                //             "rgb(209,150,226)", "rgb(127,235,144)", "rgb(252,188,189)", "rgb(247,175,81)",];
-                //         const colorPalette = Cast(cvd.colorPalette, listSpec("string"));
-                //         if (!colorPalette) cvd.colorPalette = new List<string>(defaultPalette);
-                //     }
-                //     const cp = Cast(cvd.colorPalette, listSpec("string")) as string[];
-                //     let closest = 0;
-                //     let dist = 10000000;
-                //     const ccol = Utils.fromRGBAstr(StrCast(targetDoc.backgroundColor));
-                //     for (let i = 0; i < cp.length; i++) {
-                //         const cpcol = Utils.fromRGBAstr(cp[i]);
-                //         const d = Math.sqrt((ccol.r - cpcol.r) * (ccol.r - cpcol.r) + (ccol.b - cpcol.b) * (ccol.b - cpcol.b) + (ccol.g - cpcol.g) * (ccol.g - cpcol.g));
-                //         if (d < dist) {
-                //             dist = d;
-                //             closest = i;
-                //         }
-                //     }
-                //     cp[closest] = "rgba(" + color.rgb.r + "," + color.rgb.g + "," + color.rgb.b + "," + color.rgb.a + ")";
-                //     cvd.colorPalette = new List(cp);
-                //     matchedColor = cp[closest];
-                //     ruleProvider = (view.props.Document.heading && ruleProvider) ? ruleProvider : undefined;
-                //     ruleProvider && ((Doc.GetProto(ruleProvider)["ruleColor_" + NumCast(view.props.Document.heading)] = Utils.toRGBAstr(color.rgb)));
-                // }
-                (!ruleProvider && targetDoc) && (Doc.Layout(view.props.Document).backgroundColor = matchedColor);
+                targetDoc && (Doc.Layout(view.props.Document).backgroundColor = matchedColor);
 
                 return {
                     target: targetDoc,
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 79e0cfea5..cd4e9a1a6 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -276,7 +276,6 @@ export class MainView extends React.Component {
             addDocTab={this.addDocTabFunc}
             pinToPres={emptyFunction}
             onClick={undefined}
-            ruleProvider={undefined}
             removeDocument={undefined}
             ScreenToLocalTransform={Transform.Identity}
             ContentScaling={returnOne}
@@ -377,7 +376,6 @@ export class MainView extends React.Component {
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={undefined}
-                    ruleProvider={undefined}
                     onClick={undefined}
                     ScreenToLocalTransform={Transform.Identity}
                     ContentScaling={returnOne}
@@ -404,7 +402,6 @@ export class MainView extends React.Component {
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={returnFalse}
-                    ruleProvider={undefined}
                     onClick={undefined}
                     ScreenToLocalTransform={this.mainContainerXf}
                     ContentScaling={returnOne}
@@ -500,7 +497,6 @@ export class MainView extends React.Component {
                     addDocTab={this.addDocTabFunc}
                     pinToPres={emptyFunction}
                     removeDocument={this.remButtonDoc}
-                    ruleProvider={undefined}
                     onClick={undefined}
                     ScreenToLocalTransform={this.buttonBarXf}
                     ContentScaling={returnOne}
diff --git a/src/client/views/OverlayView.tsx b/src/client/views/OverlayView.tsx
index 350a75d29..295cd7c6e 100644
--- a/src/client/views/OverlayView.tsx
+++ b/src/client/views/OverlayView.tsx
@@ -178,7 +178,6 @@ export class OverlayView extends React.Component {
                     // select={emptyFunction}
                     // layoutKey={"layout"}
                     bringToFront={emptyFunction}
-                    ruleProvider={undefined}
                     addDocument={undefined}
                     removeDocument={undefined}
                     ContentScaling={returnOne}
diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx
index 811c24f53..10aac96a0 100644
--- a/src/client/views/Palette.tsx
+++ b/src/client/views/Palette.tsx
@@ -56,7 +56,6 @@ export default class Palette extends React.Component<PaletteProps> {
                             addDocTab={returnFalse}
                             pinToPres={emptyFunction}
                             removeDocument={undefined}
-                            ruleProvider={undefined}
                             onClick={undefined}
                             ScreenToLocalTransform={Transform.Identity}
                             ContentScaling={returnOne}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 5f9b4e0c7..125cd828f 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -723,7 +723,6 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
             bringToFront={emptyFunction}
             addDocument={undefined}
             removeDocument={undefined}
-            ruleProvider={undefined}
             ContentScaling={this.contentScaling}
             PanelWidth={this.panelWidth}
             PanelHeight={this.panelHeight}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 77af2dc0e..8bf6b4202 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -108,7 +108,6 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                                 addDocTab={this.props.addDocTab}
                                 pinToPres={emptyFunction}
                                 removeDocument={this.props.removeDocument}
-                                ruleProvider={undefined}
                                 onClick={undefined}
                                 ScreenToLocalTransform={this.getTransform(dref)}
                                 ContentScaling={returnOne}
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 79a34bc00..7e990ab4d 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -145,7 +145,6 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
             DataDoc: this.props.rowProps.original,
             LibraryPath: [],
             fieldKey: this.props.rowProps.column.id as string,
-            ruleProvider: undefined,
             ContainingCollectionView: this.props.CollectionView,
             ContainingCollectionDoc: this.props.CollectionView && this.props.CollectionView.props.Document,
             isSelected: returnFalse,
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index b466d9511..994c7b351 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -144,7 +144,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
                 LibraryPath={this.props.LibraryPath}
                 childDocs={this.childDocs}
                 renderDepth={this.props.renderDepth}
-                ruleProvider={this.props.Document.isRuleProvider && layoutDoc && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
                 PanelWidth={this.previewWidth}
                 PanelHeight={this.previewHeight}
                 getTransform={this.getPreviewTransform}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b2e4b9d90..ec22bb813 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -39,7 +39,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
-    @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized).map(d => (Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, d).layout as Doc) || d); }
+    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => !pair.layout.isMinimized).map(pair => pair.layout); }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@@ -167,7 +167,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             LibraryPath={this.props.LibraryPath}
             showOverlays={this.overlays}
             renderDepth={this.props.renderDepth + 1}
-            ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
             fitToBox={this.props.fitToBox}
             onClick={layoutDoc.isTemplateDoc ? this.onClickHandler : this.onChildClickHandler}
             PanelWidth={width}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 6c4f940b6..063b5c5df 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -40,7 +40,6 @@ export interface CollectionViewProps extends FieldViewProps {
 
 export interface SubCollectionViewProps extends CollectionViewProps {
     CollectionView: Opt<CollectionView>;
-    ruleProvider: Doc | undefined;
     children?: never | (() => JSX.Element[]) | React.ReactNode;
     isAnnotationOverlay?: boolean;
     annotationsKey: string;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2c8c53f97..ec348e74b 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -43,7 +43,6 @@ export interface TreeViewProps {
     prevSibling?: Doc;
     renderDepth: number;
     deleteDoc: (doc: Doc) => boolean;
-    ruleProvider: Doc | undefined;
     moveDocument: DragManager.MoveFunction;
     dropAction: "alias" | "copy" | undefined;
     addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string, libraryPath?: Doc[]) => boolean;
@@ -352,7 +351,6 @@ class TreeView extends React.Component<TreeViewProps> {
                     LibraryPath={emptyPath}
                     renderDepth={this.props.renderDepth + 1}
                     showOverlays={this.noOverlays}
-                    ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
                     fitToBox={this.boundsOfCollectionDocument !== undefined}
                     PanelWidth={this.docWidth}
                     PanelHeight={this.docHeight}
@@ -559,7 +557,6 @@ class TreeView extends React.Component<TreeViewProps> {
                 containingCollection={containingCollection}
                 prevSibling={docs[i]}
                 treeViewId={treeViewId}
-                ruleProvider={containingCollection.isRuleProvider && pair.layout.type !== DocumentType.TEXT ? containingCollection : containingCollection.ruleProvider as Doc}
                 key={child[Id]}
                 indentDocument={indent}
                 outdentDocument={outdent}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index aa1559416..65953dbdc 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -54,7 +54,6 @@ export const panZoomSchema = createSchema({
     arrangeScript: ScriptField,
     arrangeInit: ScriptField,
     useClusters: "boolean",
-    isRuleProvider: "boolean",
     fitToBox: "boolean",
     xPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
@@ -103,14 +102,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
     private addLiveTextBox = (newBox: Doc) => {
         FormattedTextBox.SelectOnLoad = newBox[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-        const maxHeading = this.childDocs.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
-        let heading = maxHeading === 0 || this.childDocs.length === 0 ? 1 : maxHeading === 1 ? 2 : 0;
-        if (heading === 0) {
-            const sorted = this.childDocs.filter(d => d.type === DocumentType.TEXT && d.data_ext instanceof Doc && d.data_ext.lastModified).sort((a, b) => DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date > DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? 1 :
-                DateCast((Cast(a.data_ext, Doc) as Doc).lastModified).date < DateCast((Cast(b.data_ext, Doc) as Doc).lastModified).date ? -1 : 0);
-            heading = !sorted.length ? Math.max(1, maxHeading) : NumCast(sorted[sorted.length - 1].heading) === 1 ? 2 : NumCast(sorted[sorted.length - 1].heading);
-        }
-        !this.Document.isRuleProvider && (newBox.heading = heading);
         this.addDocument(newBox);
     }
     private addDocument = (newBox: Doc) => {
@@ -412,16 +403,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
         if (!this.isAnnotationOverlay) {
             PDFMenu.Instance.fadeOut(true);
-            const minx = docs.length ? NumCast(docs[0].x) : 0;
-            const maxx = docs.length ? NumCast(docs[0].width) + minx : minx;
-            const miny = docs.length ? NumCast(docs[0].y) : 0;
-            const maxy = docs.length ? NumCast(docs[0].height) + miny : miny;
+            const minx = this.childDataProvider(docs[0]).x;//docs.length ? NumCast(docs[0].x) : 0;
+            const miny = this.childDataProvider(docs[0]).y;//docs.length ? NumCast(docs[0].y) : 0;
+            const maxx = this.childDataProvider(docs[0]).width + minx;//docs.length ? NumCast(docs[0].width) + minx : minx;
+            const maxy = this.childDataProvider(docs[0]).height + miny;//docs.length ? NumCast(docs[0].height) + miny : miny;
             const ranges = docs.filter(doc => doc).reduce((range, doc) => {
                 const layoutDoc = Doc.Layout(doc);
-                const x = NumCast(doc.x);
-                const xe = x + NumCast(layoutDoc.width);
-                const y = NumCast(doc.y);
-                const ye = y + NumCast(layoutDoc.height);
+                const x = this.childDataProvider(doc).x;//NumCast(doc.x);
+                const y = this.childDataProvider(doc).y;//NumCast(doc.y);
+                const xe = this.childDataProvider(doc).width + x;//x + NumCast(layoutDoc.width);
+                const ye = this.childDataProvider(doc).height + y; //y + NumCast(layoutDoc.height);
                 return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
                 [range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
             }, [[minx, maxx], [miny, maxy]]);
@@ -694,7 +685,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             Document: childLayout,
             LibraryPath: this.libraryPath,
             layoutKey: undefined,
-            ruleProvider: this.Document.isRuleProvider && childLayout.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider, //bcz: hack! - currently ruleProviders apply to documents in nested colleciton, not direct children of themselves
             //onClick: undefined, // this.props.onClick,  // bcz: check this out -- I don't think we want to inherit click handlers, or we at least need a way to ignore them
             onClick: this.onChildClickHandler,
             ScreenToLocalTransform: childLayout.z ? this.getTransformOverlay : this.getTransform,
@@ -779,7 +769,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             computedElementData.elements.push({
                 ele: <CollectionFreeFormDocumentView key={pair.layout[Id]}  {...this.getChildDocumentViewProps(pair.layout, pair.data)}
                     dataProvider={this.childDataProvider}
-                    ruleProvider={this.Document.isRuleProvider ? this.props.Document : this.props.ruleProvider}
                     jitterRotation={NumCast(this.props.Document.jitterRotation)}
                     fitToBox={this.props.fitToBox || this.Document.freeformLayoutEngine === "pivot"} />,
                 bounds: this.childDataProvider(pair.layout)
@@ -827,20 +816,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }, "arrange contents");
     }
 
-    autoFormat = () => {
-        this.Document.isRuleProvider = !this.Document.isRuleProvider;
-        // find rule colorations when rule providing is turned on by looking at each document to see if it has a coloring -- if so, use it's color as the rule for its associated heading.
-        this.Document.isRuleProvider && this.childLayoutPairs.map(pair =>
-            // iterate over the children of a displayed document (or if the displayed document is a template, iterate over the children of that template)
-            DocListCast(Doc.Layout(pair.layout).data).map(heading => {
-                const headingPair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, heading);
-                const headingLayout = headingPair.layout && (pair.layout.data_ext instanceof Doc) && (pair.layout.data_ext[`Layout[${headingPair.layout[Id]}]`] as Doc) || headingPair.layout;
-                if (headingLayout && NumCast(headingLayout.heading) > 0 && headingLayout.backgroundColor !== headingLayout.defaultBackgroundColor) {
-                    Doc.GetProto(this.props.Document)["ruleColor_" + NumCast(headingLayout.heading)] = headingLayout.backgroundColor;
-                }
-            })
-        );
-    }
 
     analyzeStrokes = async () => {
         const children = await DocListCastAsync(this.dataDoc.data);
@@ -908,7 +883,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         layoutItems.push({ description: `${this.Document.LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document.LODdisable = !this.Document.LODdisable, icon: "table" });
         layoutItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document.fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
         layoutItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
-        layoutItems.push({ description: `${this.Document.isRuleProvider ? "Stop Auto Format" : "Auto Format"}`, event: this.autoFormat, icon: "chalkboard" });
         layoutItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
         layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" });
         layoutItems.push({ description: "Jitter Rotation", event: action(() => this.props.Document.jitterRotation = 10), icon: "paint-brush" });
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 614a68e7a..cd78f5d49 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -73,10 +73,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         .scale(1 / this.contentScaling())
 
     borderRounding = () => {
-        const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
         const ld = this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] instanceof Doc ? this.layoutDoc[StrCast(this.layoutDoc.layoutKey, "layout")] as Doc : undefined;
-        const br = StrCast((ld || this.props.Document).borderRounding);
-        return !br && ruleRounding ? ruleRounding : br;
+        return StrCast((ld || this.props.Document).borderRounding);
     }
 
     @computed
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index e97445f27..96102e0e8 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -24,7 +24,6 @@ interface ContentFittingDocumentViewProps {
     fitToBox?: boolean;
     PanelWidth: () => number;
     PanelHeight: () => number;
-    ruleProvider: Doc | undefined;
     focus?: (doc: Doc) => void;
     showOverlays?: (doc: Doc) => { title?: string, caption?: string };
     CollectionView?: CollectionView;
@@ -97,7 +96,6 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
                         LibraryPath={this.props.LibraryPath}
                         fitToBox={this.props.fitToBox}
                         onClick={this.props.onClick}
-                        ruleProvider={this.props.ruleProvider}
                         showOverlays={this.props.showOverlays}
                         addDocument={this.props.addDocument}
                         removeDocument={this.props.removeDocument}
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index 863ea748b..6b7b652c6 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -96,7 +96,6 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
                 addDocument={this.props.addDocument}
                 moveDocument={this.props.moveDocument}
                 removeDocument={this.props.removeDocument}
-                ruleProvider={this.props.ruleProvider}
                 addDocTab={this.props.addDocTab}
                 pinToPres={this.props.pinToPres}
                 getTransform={this.getTransform}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index b491acb8d..2570d232a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -72,7 +72,6 @@ export interface DocumentViewProps {
     renderDepth: number;
     showOverlays?: (doc: Doc) => { title?: string, titleHover?: string, caption?: string };
     ContentScaling: () => number;
-    ruleProvider: Doc | undefined;
     PanelWidth: () => number;
     PanelHeight: () => number;
     focus: (doc: Doc, willZoom: boolean, scale?: number, afterFocus?: () => boolean) => void;
@@ -875,7 +874,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             renderDepth={this.props.renderDepth}
             showOverlays={this.props.showOverlays}
             ContentScaling={this.childScaling}
-            ruleProvider={this.props.ruleProvider}
             PanelWidth={this.props.PanelWidth}
             PanelHeight={this.props.PanelHeight}
             focus={this.props.focus}
@@ -967,16 +965,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     render() {
         if (!(this.props.Document instanceof Doc)) return (null);
-        const ruleColor = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleColor_" + this.Document.heading]) : undefined;
-        const ruleRounding = this.props.ruleProvider ? StrCast(this.props.ruleProvider["ruleRounding_" + this.Document.heading]) : undefined;
         const colorSet = this.setsLayoutProp("backgroundColor");
         const clusterCol = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.clusterOverridesDefaultBackground;
         const backgroundColor = (clusterCol && !colorSet) ?
             this.props.backgroundColor(this.Document) || StrCast(this.layoutDoc.backgroundColor) :
-            ruleColor && !colorSet ? ruleColor : StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.Document);
+            StrCast(this.layoutDoc.backgroundColor) || this.props.backgroundColor(this.Document);
 
         const fullDegree = Doc.isBrushedHighlightedDegree(this.props.Document);
-        const borderRounding = this.getLayoutPropStr("borderRounding") || ruleRounding;
+        const borderRounding = this.getLayoutPropStr("borderRounding");
         const localScale = fullDegree;
 
         const animDims = this.Document.animateToDimensions ? Array.from(this.Document.animateToDimensions) : undefined;
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 6e6ee1712..538e433a9 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -27,7 +27,6 @@ export interface FieldViewProps {
     fitToBox?: boolean;
     ContainingCollectionView: Opt<CollectionView>;
     ContainingCollectionDoc: Opt<Doc>;
-    ruleProvider: Doc | undefined;
     Document: Doc;
     DataDoc?: Doc;
     LibraryPath: Doc[];
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 3814f02da..0a1a79bc4 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -89,7 +89,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     private _scrollToRegionReactionDisposer: Opt<IReactionDisposer>;
     private _reactionDisposer: Opt<IReactionDisposer>;
     private _heightReactionDisposer: Opt<IReactionDisposer>;
-    private _rulesReactionDisposer: Opt<IReactionDisposer>;
     private _proxyReactionDisposer: Opt<IReactionDisposer>;
     private _pullReactionDisposer: Opt<IReactionDisposer>;
     private _pushReactionDisposer: Opt<IReactionDisposer>;
@@ -549,36 +548,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             search => search ? this.highlightSearchTerms([Doc.SearchQuery()]) : this.unhighlightSearchTerms(),
             { fireImmediately: true });
 
-        this._rulesReactionDisposer = reaction(() => {
-            const ruleProvider = this.props.ruleProvider;
-            const heading = NumCast(this.layoutDoc.heading);
-            if (ruleProvider instanceof Doc) {
-                return {
-                    align: StrCast(ruleProvider["ruleAlign_" + heading], ""),
-                    font: StrCast(ruleProvider["ruleFont_" + heading], "Arial"),
-                    size: NumCast(ruleProvider["ruleSize_" + heading], 13)
-                };
-            }
-            return undefined;
-        },
-            action((rules: any) => {
-                this._ruleFontFamily = rules ? rules.font : "Arial";
-                this._ruleFontSize = rules ? rules.size : 0;
-                rules && setTimeout(() => {
-                    const view = this._editorView!;
-                    if (this.ProseRef) {
-                        const n = new NodeSelection(view.state.doc.resolve(0));
-                        if (this._editorView!.state.doc.textContent === "") {
-                            view.dispatch(view.state.tr.setSelection(new TextSelection(view.state.doc.resolve(0), view.state.doc.resolve(2))).
-                                replaceSelectionWith(this._editorView!.state.schema.nodes.paragraph.create({ align: rules.align }), true));
-                        } else if (n.node && n.node.type === view.state.schema.nodes.paragraph) {
-                            view.dispatch(view.state.tr.setNodeMarkup(0, n.node.type, { ...n.node.attrs, align: rules.align }));
-                        }
-                        this.tryUpdateHeight();
-                    }
-                }, 0);
-            }), { fireImmediately: true }
-        );
         this._scrollToRegionReactionDisposer = reaction(
             () => StrCast(this.layoutDoc.scrollToLinkID),
             async (scrollToLinkID) => {
@@ -849,7 +818,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
 
     componentWillUnmount() {
         this._scrollToRegionReactionDisposer && this._scrollToRegionReactionDisposer();
-        this._rulesReactionDisposer && this._rulesReactionDisposer();
         this._reactionDisposer && this._reactionDisposer();
         this._proxyReactionDisposer && this._proxyReactionDisposer();
         this._pushReactionDisposer && this._pushReactionDisposer();
@@ -1171,7 +1139,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                             addDocument={(doc: Doc) => { doc.hideSidebar = true; return this.addDocument(doc); }}
                             CollectionView={undefined}
                             ScreenToLocalTransform={() => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth), 0)}
-                            ruleProvider={undefined}
                             renderDepth={this.props.renderDepth + 1}
                             ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                             chromeCollapsed={true}>
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index f7a530790..8dedfda9b 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -185,7 +185,6 @@ export class FormattedTextBoxComment {
                                     active={returnFalse}
                                     addDocument={returnFalse}
                                     removeDocument={returnFalse}
-                                    ruleProvider={undefined}
                                     addDocTab={returnFalse}
                                     pinToPres={returnFalse}
                                     dontRegisterView={true}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index db427710e..b7e904283 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -364,7 +364,6 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 addDocument={this.addDocument}
                 CollectionView={undefined}
                 ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                ruleProvider={undefined}
                 renderDepth={this.props.renderDepth + 1}
                 ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                 chromeCollapsed={true}>
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 91f8bb3b0..46466aa0f 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -58,7 +58,6 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
             LibraryPath: [],
             ContainingCollectionView: undefined,
             ContainingCollectionDoc: undefined,
-            ruleProvider: undefined,
             fieldKey: this.props.keyName,
             isSelected: returnFalse,
             select: emptyFunction,
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 376d27380..52b4f391a 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -353,7 +353,6 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
                     addDocument={this.addDocumentWithTimestamp}
                     CollectionView={undefined}
                     ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                    ruleProvider={undefined}
                     renderDepth={this.props.renderDepth + 1}
                     ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                     chromeCollapsed={true}>
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index e9118e3ab..f21f9ff46 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -211,7 +211,6 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
                 addDocument={this.addDocument}
                 CollectionView={undefined}
                 ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                ruleProvider={undefined}
                 renderDepth={this.props.renderDepth + 1}
                 ContainingCollectionDoc={this.props.ContainingCollectionDoc}
                 chromeCollapsed={true}>
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 62467ce4d..d6829937e 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -650,7 +650,6 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 addDocument={this.addDocument}
                 CollectionView={undefined}
                 ScreenToLocalTransform={this.overlayTransform}
-                ruleProvider={undefined}
                 renderDepth={this.props.renderDepth + 1}
                 ContainingCollectionDoc={this.props.ContainingCollectionView?.props.Document}
                 chromeCollapsed={true}>
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index c02042380..92dc0f3d2 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -175,7 +175,6 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
                     fitToBox={StrCast(this.targetDoc.type).indexOf(DocumentType.COL) !== -1}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
-                    ruleProvider={undefined}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
                     PanelWidth={() => this.props.PanelWidth() - 20}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 30fcc7908..21a4560cf 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -161,7 +161,6 @@ export class SearchItem extends React.Component<SearchItemProps> {
                     fitToBox={StrCast(this.props.doc.type).indexOf(DocumentType.COL) !== -1}
                     addDocument={returnFalse}
                     removeDocument={returnFalse}
-                    ruleProvider={undefined}
                     addDocTab={returnFalse}
                     pinToPres={returnFalse}
                     getTransform={Transform.Identity}
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index ea2fc917f..b1eaeaa0a 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -38,7 +38,6 @@ export default class MobileInterface extends React.Component {
                 addDocTab={returnFalse}
                 pinToPres={emptyFunction}
                 removeDocument={undefined}
-                ruleProvider={undefined}
                 onClick={undefined}
                 ScreenToLocalTransform={Transform.Identity}
                 ContentScaling={returnOne}
-- 
cgit v1.2.3-70-g09d2


From c23d9ba83c87511a626bfe8d1da5dd981e311262 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Thu, 23 Jan 2020 18:24:38 -0500
Subject: got rid of extension docs.  changed layout-specific keys to start
 with "_" which flags them to be written to the current layout document

---
 .../apis/google_docs/GooglePhotosClientUtils.ts    |   2 +-
 src/client/apis/youtube/YoutubeBox.tsx             |   2 +-
 src/client/documents/Documents.ts                  | 109 +++++++++++----------
 src/client/util/DictationManager.ts                |   6 +-
 src/client/util/DragManager.ts                     |   2 +-
 src/client/util/DropConverter.ts                   |   3 +-
 .../util/Import & Export/DirectoryImportBox.tsx    |   4 +-
 src/client/util/RichTextRules.ts                   |   4 +-
 src/client/util/RichTextSchema.tsx                 |   4 +-
 src/client/views/DocComponent.tsx                  |   9 +-
 src/client/views/DocumentDecorations.tsx           |  40 ++++----
 src/client/views/MainView.tsx                      |  10 +-
 src/client/views/MetadataEntryMenu.tsx             |   4 +-
 src/client/views/PreviewCursor.tsx                 |   4 +-
 src/client/views/TemplateMenu.tsx                  |   4 +-
 .../views/collections/CollectionDockingView.tsx    |  20 ++--
 .../views/collections/CollectionLinearView.tsx     |  12 +--
 .../collections/CollectionMasonryViewFieldRow.tsx  |   4 +-
 .../views/collections/CollectionPivotView.tsx      |  23 ++---
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 .../views/collections/CollectionStackingView.tsx   |  34 +++----
 .../CollectionStackingViewFieldColumn.tsx          |   8 +-
 .../views/collections/CollectionStaffView.tsx      |   4 -
 src/client/views/collections/CollectionSubView.tsx |  23 ++---
 .../views/collections/CollectionTreeView.tsx       |  36 +++----
 src/client/views/collections/CollectionView.tsx    |  50 ++++------
 .../views/collections/CollectionViewChromes.tsx    |  22 ++---
 .../views/collections/ParentDocumentSelector.tsx   |  18 ++--
 .../CollectionFreeFormLayoutEngines.tsx            |   8 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  | 100 ++++++++++---------
 .../collections/collectionFreeForm/MarqueeView.tsx |  54 +++++-----
 src/client/views/linking/LinkEditor.tsx            |   2 +-
 src/client/views/linking/LinkFollowBox.tsx         |  48 ++++-----
 src/client/views/linking/LinkMenuGroup.tsx         |   2 +-
 src/client/views/nodes/AudioBox.tsx                | 101 +++++++++----------
 .../views/nodes/CollectionFreeFormDocumentView.tsx |  12 +--
 .../views/nodes/ContentFittingDocumentView.tsx     |  10 +-
 src/client/views/nodes/DocumentView.tsx            | 106 ++++++++++----------
 src/client/views/nodes/FormattedTextBox.tsx        |  26 +++--
 src/client/views/nodes/FormattedTextBoxComment.tsx |   2 +-
 src/client/views/nodes/IconBox.tsx                 |   2 +-
 src/client/views/nodes/ImageBox.tsx                |  89 ++++++++---------
 src/client/views/nodes/KeyValueBox.tsx             |   8 +-
 src/client/views/nodes/KeyValuePair.tsx            |   2 +-
 src/client/views/nodes/PDFBox.tsx                  |  22 ++---
 src/client/views/nodes/PresBox.tsx                 |   4 +-
 src/client/views/nodes/VideoBox.tsx                |  32 +++---
 src/client/views/nodes/WebBox.tsx                  |  14 +--
 src/client/views/pdf/Annotation.tsx                |  10 +-
 src/client/views/pdf/PDFViewer.tsx                 |  67 +++++++------
 .../views/presentationview/PresElementBox.tsx      |  10 +-
 src/client/views/search/SearchBox.tsx              |  16 +--
 src/client/views/search/SearchItem.tsx             |  10 +-
 src/mobile/ImageUpload.tsx                         |   2 +-
 src/new_fields/Doc.ts                              |  51 +++-------
 src/new_fields/RichTextUtils.ts                    |   2 +-
 src/new_fields/documentSchemas.ts                  |  13 +--
 src/new_fields/util.ts                             |  34 ++++++-
 src/scraping/buxton/scraper.py                     |  14 +--
 .../authentication/models/current_user_utils.ts    |  70 ++++++-------
 60 files changed, 696 insertions(+), 710 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 966d8053a..21cd20e14 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -136,7 +136,7 @@ export namespace GooglePhotos {
                 document.contentSize = upload.contentSize;
                 return document;
             });
-            const options = { width: 500, height: 500 };
+            const options = { _width: 500, _height: 500 };
             return constructor(children, options);
         };
 
diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
index d654e2530..c940bba43 100644
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -337,7 +337,7 @@ export class YoutubeBox extends React.Component<FieldViewProps> {
         const newVideoX = NumCast(this.props.Document.x);
         const newVideoY = NumCast(this.props.Document.y) + NumCast(this.props.Document.height);
 
-        addFunction(Docs.Create.VideoDocument(embeddedUrl, { title: filteredTitle, width: 400, height: 315, x: newVideoX, y: newVideoY }));
+        addFunction(Docs.Create.VideoDocument(embeddedUrl, { title: filteredTitle, _width: 400, _height: 315, x: newVideoX, y: newVideoY }));
         this.videoClicked = true;
     }
 
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 6132f787b..c665a7fd3 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -56,21 +56,28 @@ const requestImageSize = require('../util/request-image-size');
 const path = require('path');
 
 export interface DocumentOptions {
+    _panX?: number;
+    _panY?: number;
+    _width?: number;
+    _height?: number;
+    _nativeWidth?: number;
+    _nativeHeight?: number;
+    _fitWidth?: boolean;
+    _fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents
+    _LODdisable?: boolean;
+    _dropAction?: dropActionType;
+    _chromeStatus?: string;
+    _viewType?: number;
+    _gridGap?: number; // gap between items in masonry view
+    _xMargin?: number; // gap between left edge of document and start of masonry/stacking layouts
+    _yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts
     x?: number;
     y?: number;
     z?: number;
     type?: string;
-    width?: number;
-    height?: number;
-    nativeWidth?: number;
-    nativeHeight?: number;
     title?: string;
-    panX?: number;
-    panY?: number;
     page?: number;
     scale?: number;
-    fitWidth?: boolean;
-    fitToBox?: boolean; // whether a freeformview should zoom/scale to create a shrinkwrapped view of its contents
     isDisplayPanel?: boolean; // whether the panel functions as GoldenLayout "stack" used to display documents
     forceActive?: boolean;
     preventTreeViewOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expande/collapse state to be independent of other views of the same document in the tree view
@@ -79,16 +86,12 @@ export interface DocumentOptions {
     isTemplateForField?: string; // the field key for which the containing document is a rendering template
     isTemplateDoc?: boolean;
     templates?: List<string>;
-    viewType?: number;
     backgroundColor?: string | ScriptField;
     ignoreClick?: boolean;
     lockedPosition?: boolean; // lock the x,y coordinates of the document so that it can't be dragged
     lockedTransform?: boolean; // lock the panx,pany and scale parameters of the document so that it be panned/zoomed
     opacity?: number;
     defaultBackgroundColor?: string;
-    dropAction?: dropActionType;
-    chromeStatus?: string;
-    LODdisable?: boolean;
     columnWidth?: number;
     fontSize?: number;
     curPage?: number;
@@ -114,9 +117,6 @@ export interface DocumentOptions {
     onDragStart?: ScriptField; //script to execute at start of drag operation --  e.g., when a "creator" button is dragged this script generates a different document to drop
     clipboard?: Doc; //script to execute at start of drag operation --  e.g., when a "creator" button is dragged this script generates a different document to drop
     icon?: string;
-    gridGap?: number; // gap between items in masonry view
-    xMargin?: number; // gap between left edge of document and start of masonry/stacking layouts
-    yMargin?: number; // gap between top edge of dcoument and start of masonry/stacking layouts
     sourcePanel?: Doc; // panel to display in 'targetContainer' as the result of a button onClick script
     targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script
     dropConverter?: ScriptField; // script to run when documents are dropped on this Document.
@@ -158,19 +158,19 @@ export namespace Docs {
         const TemplateMap: TemplateMap = new Map([
             [DocumentType.TEXT, {
                 layout: { view: FormattedTextBox, dataField: data },
-                options: { height: 150, backgroundColor: "#f1efeb", defaultBackgroundColor: "#f1efeb" }
+                options: { _height: 150, backgroundColor: "#f1efeb", defaultBackgroundColor: "#f1efeb" }
             }],
             [DocumentType.HIST, {
                 layout: { view: HistogramBox, dataField: data },
-                options: { height: 300, backgroundColor: "black" }
+                options: { _height: 300, backgroundColor: "black" }
             }],
             [DocumentType.QUERY, {
                 layout: { view: QueryBox, dataField: data },
-                options: { width: 400 }
+                options: { _width: 400 }
             }],
             [DocumentType.COLOR, {
                 layout: { view: ColorBox, dataField: data },
-                options: { nativeWidth: 220, nativeHeight: 300 }
+                options: { _nativeWidth: 220, _nativeHeight: 300 }
             }],
             [DocumentType.IMG, {
                 layout: { view: ImageBox, dataField: data },
@@ -178,19 +178,19 @@ export namespace Docs {
             }],
             [DocumentType.WEB, {
                 layout: { view: WebBox, dataField: data },
-                options: { height: 300 }
+                options: { _height: 300 }
             }],
             [DocumentType.COL, {
                 layout: { view: CollectionView, dataField: data },
-                options: { panX: 0, panY: 0, scale: 1, width: 500, height: 500 }
+                options: { _panX: 0, _panY: 0, scale: 1, _width: 500, _height: 500 }
             }],
             [DocumentType.KVP, {
                 layout: { view: KeyValueBox, dataField: data },
-                options: { height: 150 }
+                options: { _height: 150 }
             }],
             [DocumentType.DOCUMENT, {
                 layout: { view: DocumentBox, dataField: data },
-                options: { height: 250 }
+                options: { _height: 250 }
             }],
             [DocumentType.VID, {
                 layout: { view: VideoBox, dataField: data },
@@ -198,7 +198,7 @@ export namespace Docs {
             }],
             [DocumentType.AUDIO, {
                 layout: { view: AudioBox, dataField: data },
-                options: { height: 35, backgroundColor: "lightGray" }
+                options: { _height: 35, backgroundColor: "lightGray" }
             }],
             [DocumentType.PDF, {
                 layout: { view: PDFBox, dataField: data },
@@ -206,11 +206,11 @@ export namespace Docs {
             }],
             [DocumentType.ICON, {
                 layout: { view: IconBox, dataField: data },
-                options: { width: Number(MINIMIZED_ICON_SIZE), height: Number(MINIMIZED_ICON_SIZE) },
+                options: { _width: Number(MINIMIZED_ICON_SIZE), _height: Number(MINIMIZED_ICON_SIZE) },
             }],
             [DocumentType.IMPORT, {
                 layout: { view: DirectoryImportBox, dataField: data },
-                options: { height: 150 }
+                options: { _height: 150 }
             }],
             [DocumentType.LINKDOC, {
                 data: new List<Doc>(),
@@ -228,7 +228,7 @@ export namespace Docs {
             }],
             [DocumentType.FONTICON, {
                 layout: { view: FontIconBox, dataField: data },
-                options: { width: 40, height: 40, borderRounding: "100%" },
+                options: { _width: 40, _height: 40, borderRounding: "100%" },
             }],
             [DocumentType.LINKFOLLOW, {
                 layout: { view: LinkFollowBox, dataField: data }
@@ -243,7 +243,7 @@ export namespace Docs {
         ]);
 
         // All document prototypes are initialized with at least these values
-        const defaultOptions: DocumentOptions = { x: 0, y: 0, width: 300 };
+        const defaultOptions: DocumentOptions = { x: 0, y: 0, _width: 300 };
         const suffix = "Proto";
 
         /**
@@ -321,7 +321,8 @@ export namespace Docs {
             // whatever options pertain to this specific prototype
             const options = { title, type, baseProto: true, ...defaultOptions, ...(template.options || {}) };
             options.layout = layout.view.LayoutString(layout.dataField);
-            return Doc.assign(new Doc(prototypeId, true), { ...options });
+            let doc = Doc.assign(new Doc(prototypeId, true), { layoutKey: "layout", ...options });
+            return doc;
         }
 
     }
@@ -332,7 +333,7 @@ export namespace Docs {
      */
     export namespace Create {
 
-        const delegateKeys = ["x", "y", "width", "height", "panX", "panY", "nativeWidth", "nativeHeight", "dropAction", "annotationOn", "forceActive", "fitWidth", "diableLOD"];
+        const delegateKeys = ["x", "y", "_width", "_height", "_panX", "_panY", "_viewType", "_nativeWidth", "_nativeHeight", "_dropAction", "_annotationOn", "_chromeStatus", "_forceActive", "_fitWidth", "_LODdisable"];
 
         /**
          * This function receives the relevant document prototype and uses
@@ -402,11 +403,11 @@ export namespace Docs {
             requestImageSize(target)
                 .then((size: any) => {
                     const aspect = size.height / size.width;
-                    if (!inst.nativeWidth) {
-                        inst.nativeWidth = size.width;
+                    if (!inst._nativeWidth) {
+                        inst._nativeWidth = size.width;
                     }
-                    inst.nativeHeight = NumCast(inst.nativeWidth) * aspect;
-                    inst.height = NumCast(inst.width) * aspect;
+                    inst._nativeHeight = NumCast(inst._nativeWidth) * aspect;
+                    inst._height = NumCast(inst._width) * aspect;
                 })
                 .catch((err: any) => console.log(err));
             // }
@@ -465,7 +466,7 @@ export namespace Docs {
             const ctlog = await Gateway.Instance.GetSchema(url, schemaName);
             if (ctlog && ctlog.schemas) {
                 const schema = ctlog.schemas[0];
-                const schemaDoc = Docs.Create.TreeDocument([], { ...options, nativeWidth: undefined, nativeHeight: undefined, width: 150, height: 100, title: schema.displayName! });
+                const schemaDoc = Docs.Create.TreeDocument([], { ...options, _nativeWidth: undefined, _nativeHeight: undefined, _width: 150, _height: 100, title: schema.displayName! });
                 const schemaDocuments = Cast(schemaDoc.data, listSpec(Doc), []);
                 if (!schemaDocuments) {
                     return;
@@ -482,13 +483,13 @@ export namespace Docs {
                                 new AttributeTransformationModel(atmod, AggregateFunction.None),
                                 new AttributeTransformationModel(atmod, AggregateFunction.Count),
                                 new AttributeTransformationModel(atmod, AggregateFunction.Count));
-                            docs.push(Docs.Create.HistogramDocument(histoOp, { ...columnOptions, width: 200, height: 200, title: attr.displayName! }));
+                            docs.push(Docs.Create.HistogramDocument(histoOp, { ...columnOptions, _width: 200, _height: 200, title: attr.displayName! }));
                         }
                     }));
                 });
                 return schemaDoc;
             }
-            return Docs.Create.TreeDocument([], { width: 50, height: 100, title: schemaName });
+            return Docs.Create.TreeDocument([], { _width: 50, _height: 100, title: schemaName });
         }
 
         export function WebDocument(url: string, options: DocumentOptions = {}) {
@@ -508,31 +509,31 @@ export namespace Docs {
         }
 
         export function FreeformDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Freeform }, id);
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Freeform }, id);
         }
 
         export function LinearDocument(documents: Array<Doc>, options: DocumentOptions, id?: string) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Linear }, id);
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", backgroundColor: "black", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Linear }, id);
         }
 
         export function SchemaDocument(schemaColumns: SchemaHeaderField[], documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List(schemaColumns), ...options, viewType: CollectionViewType.Schema });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List(schemaColumns), ...options, _viewType: CollectionViewType.Schema });
         }
 
         export function TreeDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Tree });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Tree });
         }
 
         export function StackingDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Stacking });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Stacking });
         }
 
         export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Multicolumn });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Multicolumn });
         }
 
         export function MasonryDocument(documents: Array<Doc>, options: DocumentOptions) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, viewType: CollectionViewType.Masonry });
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { _chromeStatus: "collapsed", schemaColumns: new List([new SchemaHeaderField("title", "#f1efeb")]), ...options, _viewType: CollectionViewType.Masonry });
         }
 
         export function ButtonDocument(options?: DocumentOptions) {
@@ -553,7 +554,7 @@ export namespace Docs {
         }
 
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
-            const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+            const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
             Doc.GetProto(inst).data = new List<Doc>(documents);
             return inst;
         }
@@ -714,24 +715,24 @@ export namespace Docs {
             let ctor: ((path: string, options: DocumentOptions) => (Doc | Promise<Doc | undefined>)) | undefined = undefined;
             if (type.indexOf("image") !== -1) {
                 ctor = Docs.Create.ImageDocument;
-                if (!options.width) options.width = 300;
+                if (!options._width) options._width = 300;
             }
             if (type.indexOf("video") !== -1) {
                 ctor = Docs.Create.VideoDocument;
-                if (!options.width) options.width = 600;
-                if (!options.height) options.height = options.width * 2 / 3;
+                if (!options._width) options._width = 600;
+                if (!options._height) options._height = options._width * 2 / 3;
             }
             if (type.indexOf("audio") !== -1) {
                 ctor = Docs.Create.AudioDocument;
             }
             if (type.indexOf("pdf") !== -1) {
                 ctor = Docs.Create.PdfDocument;
-                if (!options.width) options.width = 400;
-                if (!options.height) options.height = options.width * 1200 / 927;
+                if (!options._width) options._width = 400;
+                if (!options._height) options._height = options._width * 1200 / 927;
             }
             if (type.indexOf("excel") !== -1) {
                 ctor = Docs.Create.DBDocument;
-                options.dropAction = "copy";
+                options._dropAction = "copy";
             }
             if (type.indexOf("html") !== -1) {
                 if (path.includes(window.location.hostname)) {
@@ -742,15 +743,15 @@ export namespace Docs {
                             const alias = Doc.MakeAlias(field);
                             alias.x = options.x || 0;
                             alias.y = options.y || 0;
-                            alias.width = options.width || 300;
-                            alias.height = options.height || options.width || 300;
+                            alias._width = options._width || 300;
+                            alias._height = options._height || options._width || 300;
                             return alias;
                         }
                         return undefined;
                     });
                 }
                 ctor = Docs.Create.WebDocument;
-                options = { height: options.width, ...options, title: path, nativeWidth: undefined };
+                options = { _height: options._width, ...options, title: path, _nativeWidth: undefined };
             }
             return ctor ? ctor(path, options) : undefined;
         }
diff --git a/src/client/util/DictationManager.ts b/src/client/util/DictationManager.ts
index 3d8f2d234..a99e3bc4f 100644
--- a/src/client/util/DictationManager.ts
+++ b/src/client/util/DictationManager.ts
@@ -325,14 +325,14 @@ export namespace DictationManager {
 
             ["open fields", {
                 action: (target: DocumentView) => {
-                    const kvp = Docs.Create.KVPDocument(target.props.Document, { width: 300, height: 300 });
+                    const kvp = Docs.Create.KVPDocument(target.props.Document, { _width: 300, _height: 300 });
                     target.props.addDocTab(kvp, target.props.DataDoc, "onRight");
                 }
             }],
 
             ["new outline", {
                 action: (target: DocumentView) => {
-                    const newBox = Docs.Create.TextDocument({ width: 400, height: 200, title: "My Outline" });
+                    const newBox = Docs.Create.TextDocument({ _width: 400, _height: 200, title: "My Outline" });
                     newBox.autoHeight = true;
                     const proto = newBox.proto!;
                     const prompt = "Press alt + r to start dictating here...";
@@ -379,7 +379,7 @@ export namespace DictationManager {
                 expression: /view as (freeform|stacking|masonry|schema|tree)/g,
                 action: (target: DocumentView, matches: RegExpExecArray) => {
                     const mode = CollectionViewType.valueOf(matches[1]);
-                    mode && (target.props.Document.viewType = mode);
+                    mode && (target.props.Document._viewType = mode);
                 },
                 restrictTo: [DocumentType.COL]
             }
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index df2f5fe3c..601a7e856 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -205,7 +205,7 @@ export namespace DragManager {
     // drag a button template and drop a new button 
     export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
         const finishDrag = (e: DragCompleteEvent) => {
-            const bd = Docs.Create.ButtonDocument({ width: 150, height: 50, title: title });
+            const bd = Docs.Create.ButtonDocument({ _width: 150, _height: 50, title: title });
             bd.onClick = ScriptField.MakeScript(script);
             params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc)));
             initialize && initialize(bd);
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 66caf52cb..9c068d2d7 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -1,5 +1,4 @@
 import { DragManager } from "./DragManager";
-import { CollectionViewType } from "../views/collections/CollectionView";
 import { Doc, DocListCast } from "../../new_fields/Doc";
 import { DocumentType } from "../documents/DocumentTypes";
 import { ObjectField } from "../../new_fields/ObjectField";
@@ -34,7 +33,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
             } else {
                 layoutDoc.isTemplateDoc = (layoutDoc.type === DocumentType.TEXT || layoutDoc.layout instanceof Doc) && !data.userDropAction;
             }
-            dbox = Docs.Create.FontIconDocument({ nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" });
+            dbox = Docs.Create.FontIconDocument({ _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, backgroundColor: StrCast(doc.backgroundColor), title: "Custom", icon: layoutDoc.isTemplateDoc ? "font" : "bolt" });
             dbox.dragFactory = layoutDoc;
             dbox.removeDropProperties = doc.removeDropProperties instanceof ObjectField ? ObjectField.MakeCopy(doc.removeDropProperties) : undefined;
             dbox.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
diff --git a/src/client/util/Import & Export/DirectoryImportBox.tsx b/src/client/util/Import & Export/DirectoryImportBox.tsx
index 5b5bffd8c..c7c94abed 100644
--- a/src/client/util/Import & Export/DirectoryImportBox.tsx	
+++ b/src/client/util/Import & Export/DirectoryImportBox.tsx	
@@ -145,8 +145,8 @@ export default class DirectoryImportBox extends React.Component<FieldViewProps>
         const offset: number = this.persistent ? (height === 0 ? 0 : height + 30) : 0;
         const options: DocumentOptions = {
             title: `Import of ${directory}`,
-            width: 1105,
-            height: 500,
+            _width: 1105,
+            _height: 500,
             x: NumCast(doc.x),
             y: NumCast(doc.y) + offset
         };
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index 0ee9481f0..fb22e0d18 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -79,7 +79,7 @@ export const inpRules = {
                 const value = state.doc.textBetween(start, end);
                 if (value) {
                     DocServer.GetRefField(value).then(docx => {
-                        const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500, }, value);
+                        const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: value, _width: 500, _height: 500, }, value);
                         DocUtils.Publish(target, value, returnFalse, returnFalse);
                         DocUtils.MakeLink({ doc: (schema as any).Document }, { doc: target }, "portal link", "");
                     });
@@ -196,7 +196,7 @@ export const inpRules = {
         new InputRule(
             new RegExp(/%#$/),
             (state, match, start, end) => {
-                const target = Docs.Create.TextDocument({ width: 75, height: 35, backgroundColor: "yellow", annotationOn: FormattedTextBox.FocusedBox!.dataDoc, autoHeight: true, fontSize: 9, title: "inline comment" });
+                const target = Docs.Create.TextDocument({ _width: 75, _height: 35, backgroundColor: "yellow", annotationOn: FormattedTextBox.FocusedBox!.dataDoc, autoHeight: true, fontSize: 9, title: "inline comment" });
                 const node = (state.doc.resolve(start) as any).nodeAfter;
                 const newNode = schema.nodes.dashComment.create({ docid: target[Id] });
                 const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 35, title: "dashDoc", docid: target[Id], float: "right" });
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index fe7ab31a8..d64098e5f 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -703,7 +703,7 @@ export class DashDocView {
         const { scale, translateX, translateY } = Utils.GetScreenTransform(this._outer);
         return new Transform(-translateX, -translateY, 1).scale(1 / this.contentScaling() / scale);
     }
-    contentScaling = () => NumCast(this._dashDoc!.nativeWidth) > 0 && !this._dashDoc!.ignoreAspect ? this._dashDoc![WidthSym]() / NumCast(this._dashDoc!.nativeWidth) : 1;
+    contentScaling = () => NumCast(this._dashDoc!._nativeWidth) > 0 && !this._dashDoc!.ignoreAspect ? this._dashDoc![WidthSym]() / NumCast(this._dashDoc!._nativeWidth) : 1;
     outerFocus = (target: Doc) => this._textBox.props.focus(this._textBox.props.Document);  // ideally, this would scroll to show the focus target
     constructor(node: any, view: any, getPos: any, tbox: FormattedTextBox) {
         this._textBox = tbox;
@@ -758,7 +758,7 @@ export class DashDocView {
                 ReactDOM.render(<DocumentView
                     Document={dashDoc}
                     LibraryPath={tbox.props.LibraryPath}
-                    fitToBox={BoolCast(dashDoc.fitToBox)}
+                    fitToBox={BoolCast(dashDoc._fitToBox)}
                     addDocument={returnFalse}
                     removeDocument={removeDoc}
                     ScreenToLocalTransform={this.getDocTransform}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 1ffbd80ca..6d185ff87 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -35,7 +35,6 @@ export function DocExtendableComponent<P extends DocExtendableProps, T>(schemaCt
         @computed get Document(): T { return schemaCtor(this.props.Document); }
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
         @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
-        @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
         active = (outsideReaction?: boolean) => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0);//  && !InkingControl.Instance.selectedTool;  // bcz: inking state shouldn't affect static tools 
     }
     return Component;
@@ -59,14 +58,12 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         @computed get Document(): T { return schemaCtor(this.props.Document); }
         @computed get layoutDoc() { return Doc.Layout(this.props.Document); }
         @computed get dataDoc() { return (this.props.DataDoc && (this.props.Document.isTemplateForField || this.props.Document.isTemplateDoc) ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
-        @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
-        @computed get extensionDocSync() { return Doc.fieldExtensionDocSync(this.dataDoc, this.props.fieldKey); }
-        @computed get annotationsKey() { return "annotations"; }
+        @computed get annotationsKey() { return this.props.fieldKey+"-annotations"; }
 
         @action.bound
         removeDocument(doc: Doc): boolean {
             Doc.GetProto(doc).annotationOn = undefined;
-            const value = this.extensionDoc && Cast(this.extensionDoc[this.annotationsKey], listSpec(Doc), []);
+            const value = Cast(this.dataDoc[this.props.fieldKey+"-"+this.annotationsKey], listSpec(Doc), []);
             const index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1;
             return index !== -1 && value && value.splice(index, 1) ? true : false;
         }
@@ -79,7 +76,7 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
         @action.bound
         addDocument(doc: Doc): boolean {
             Doc.GetProto(doc).annotationOn = this.props.Document;
-            return this.extensionDoc && Doc.AddDocToList(this.extensionDoc, this.annotationsKey, doc) ? true : false;
+            return Doc.AddDocToList(this.dataDoc, this.annotationsKey, doc) ? true : false;
         }
 
         whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index e6a119d1f..095b9b17c 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -317,8 +317,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
 
         IconBox.AutomaticTitle(iconDoc);
         //iconDoc.proto![this._fieldKey] = selected.length > 1 ? "collection" : undefined;
-        iconDoc.width = Number(MINIMIZED_ICON_SIZE);
-        iconDoc.height = Number(MINIMIZED_ICON_SIZE);
+        iconDoc._width = Number(MINIMIZED_ICON_SIZE);
+        iconDoc._height = Number(MINIMIZED_ICON_SIZE);
         iconDoc.x = NumCast(doc.x);
         iconDoc.y = NumCast(doc.y) - 24;
         iconDoc.maximizedDocs = new List<Doc>(selected.map(s => s.props.Document));
@@ -454,10 +454,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) {
                 const doc = PositionDocument(element.props.Document);
                 const layoutDoc = PositionDocument(Doc.Layout(element.props.Document));
-                let nwidth = layoutDoc.nativeWidth || 0;
-                let nheight = layoutDoc.nativeHeight || 0;
-                const width = (layoutDoc.width || 0);
-                const height = (layoutDoc.height || (nheight / nwidth * width));
+                let nwidth = layoutDoc._nativeWidth || 0;
+                let nheight = layoutDoc._nativeHeight || 0;
+                const width = (layoutDoc._width || 0);
+                const height = (layoutDoc._height || (nheight / nwidth * width));
                 const scale = element.props.ScreenToLocalTransform().Scale * element.props.ContentScaling();
                 const actualdW = Math.max(width + (dW * scale), 20);
                 const actualdH = Math.max(height + (dH * scale), 20);
@@ -466,33 +466,33 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 const fixedAspect = e.ctrlKey || (!layoutDoc.ignoreAspect && nwidth && nheight);
                 if (fixedAspect && e.ctrlKey && layoutDoc.ignoreAspect) {
                     layoutDoc.ignoreAspect = false;
-                    layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0;
-                    layoutDoc.nativeHeight = nheight = layoutDoc.height || 0;
+                    layoutDoc._nativeWidth = nwidth = layoutDoc._width || 0;
+                    layoutDoc._nativeHeight = nheight = layoutDoc._height || 0;
                 }
                 if (fixedAspect && (!nwidth || !nheight)) {
-                    layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0;
-                    layoutDoc.nativeHeight = nheight = layoutDoc.height || 0;
+                    layoutDoc._nativeWidth = nwidth = layoutDoc._width || 0;
+                    layoutDoc._nativeHeight = nheight = layoutDoc._height || 0;
                 }
                 if (nwidth > 0 && nheight > 0 && !layoutDoc.ignoreAspect) {
                     if (Math.abs(dW) > Math.abs(dH)) {
                         if (!fixedAspect) {
-                            layoutDoc.nativeWidth = actualdW / (layoutDoc.width || 1) * (layoutDoc.nativeWidth || 0);
+                            layoutDoc._nativeWidth = actualdW / (layoutDoc._width || 1) * (layoutDoc._nativeWidth || 0);
                         }
-                        layoutDoc.width = actualdW;
-                        if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.height = nheight / nwidth * layoutDoc.width;
-                        else layoutDoc.height = actualdH;
+                        layoutDoc._width = actualdW;
+                        if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._height = nheight / nwidth * layoutDoc._width;
+                        else layoutDoc._height = actualdH;
                     }
                     else {
                         if (!fixedAspect) {
-                            layoutDoc.nativeHeight = actualdH / (layoutDoc.height || 1) * (doc.nativeHeight || 0);
+                            layoutDoc._nativeHeight = actualdH / (layoutDoc._height || 1) * (doc._nativeHeight || 0);
                         }
-                        layoutDoc.height = actualdH;
-                        if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.width = nwidth / nheight * layoutDoc.height;
-                        else layoutDoc.width = actualdW;
+                        layoutDoc._height = actualdH;
+                        if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._width = nwidth / nheight * layoutDoc._height;
+                        else layoutDoc._width = actualdW;
                     }
                 } else {
-                    dW && (layoutDoc.width = actualdW);
-                    dH && (layoutDoc.height = actualdH);
+                    dW && (layoutDoc._width = actualdW);
+                    dH && (layoutDoc._height = actualdH);
                     dH && layoutDoc.autoHeight && (layoutDoc.autoHeight = false);
                 }
             }
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index cd4e9a1a6..2297c2bb3 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -176,9 +176,9 @@ export class MainView extends React.Component {
         } else {
             if (received && this._urlState.sharing) {
                 reaction(() => CollectionDockingView.Instance && CollectionDockingView.Instance.initialized,
-                    initialized => initialized && received && DocServer.GetRefField(received).then(field => {
-                        if (field instanceof Doc && field.viewType !== CollectionViewType.Docking) {
-                            CollectionDockingView.AddRightSplit(field, undefined);
+                    initialized => initialized && received && DocServer.GetRefField(received).then(docField => {
+                        if (docField instanceof Doc && docField._viewType !== CollectionViewType.Docking) {
+                            CollectionDockingView.AddRightSplit(docField, undefined);
                         }
                     }),
                 );
@@ -199,8 +199,8 @@ export class MainView extends React.Component {
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
-            width: this._panelWidth * .7,
-            height: this._panelHeight,
+            _width: this._panelWidth * .7,
+            _height: this._panelHeight,
             title: "Collection " + workspaceCount,
             backgroundColor: "white"
         };
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 243cdb8f6..a48e8f508 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -178,11 +178,11 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
         }
         docSource = docSource as Doc[] | Doc;
         if (docSource instanceof Doc) {
-            if (docSource.viewType === undefined) {
+            if (docSource._viewType === undefined) {
                 return (null);
             }
         } else if (Array.isArray(docSource)) {
-            if (!docSource.every(doc => doc.viewType !== undefined)) {
+            if (!docSource.every(doc => doc._viewType !== undefined)) {
                 return null;
             }
         }
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 9706d0f99..831d9ca0b 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -31,8 +31,8 @@ export class PreviewCursor extends React.Component<{}> {
                 if (e.clipboardData.getData("text/plain").indexOf("www.youtube.com/watch") !== -1) {
                     const url = e.clipboardData.getData("text/plain").replace("youtube.com/watch?v=", "youtube.com/embed/");
                     return PreviewCursor._addDocument(Docs.Create.VideoDocument(url, {
-                        title: url, width: 400, height: 315,
-                        nativeWidth: 600, nativeHeight: 472.5,
+                        title: url, _width: 400, _height: 315,
+                        _nativeWidth: 600, _nativeHeight: 472.5,
                         x: newPoint[0], y: newPoint[1]
                     }));
                 }
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index d953d3bab..d6cc394d8 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -104,7 +104,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
     toggleChrome = (): void => {
         this.props.docs.map(dv => {
             const layout = Doc.Layout(dv.Document);
-            layout.chromeStatus = (layout.chromeStatus !== "disabled" ? "disabled" : "enabled");
+            layout._chromeStatus = (layout._chromeStatus !== "disabled" ? "disabled" : "enabled");
         });
     }
     onAliasButtonUp = (e: PointerEvent): void => {
@@ -150,7 +150,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         templateMenu.push(<OtherToggle key={"float"} name={"Float"} checked={this.props.docs[0].Document.z ? true : false} toggle={this.toggleFloat} />);
         templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
         templateMenu.push(<OtherToggle key={"narrative"} name={"Narrative"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") === "layout_narrative"} toggle={this.toggleNarrative} />);
-        templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout.chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
+        templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout._chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
         return (
             <Flyout anchorPoint={anchorPoints.LEFT_TOP}
                 content={<ul className="template-list" ref={this._dragRef} style={{ display: "block" }}>
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 125cd828f..75e43a875 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -235,7 +235,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
             if (found) {
                 Doc.GetProto(found.props.Document).data = new List<Doc>([document]);
             } else {
-                const stackView = Docs.Create.FreeformDocument([document], { fitToBox: true, isDisplayPanel: true, title: "document viewer" });
+                const stackView = Docs.Create.FreeformDocument([document], { _fitToBox: true, isDisplayPanel: true, title: "document viewer" });
                 CollectionDockingView.AddRightSplit(stackView, undefined, []);
             }
         }
@@ -505,7 +505,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         stack.header.element[0].style.backgroundColor = DocServer.Control.isReadOnly() ? "#228540" : undefined;
         stack.header.element.on('mousedown', (e: any) => {
             if (e.target === stack.header.element[0] && e.button === 1) {
-                this.AddTab(stack, Docs.Create.FreeformDocument([], { width: this.props.PanelWidth(), height: this.props.PanelHeight(), title: "Untitled Collection" }), undefined);
+                this.AddTab(stack, Docs.Create.FreeformDocument([], { _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), title: "Untitled Collection" }), undefined);
             }
         });
 
@@ -665,19 +665,19 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
     }
 
     get layoutDoc() { return this._document && Doc.Layout(this._document); }
-    panelWidth = () => this.layoutDoc && this.layoutDoc.maxWidth ? Math.min(Math.max(NumCast(this.layoutDoc.width), NumCast(this.layoutDoc.nativeWidth)), this._panelWidth) : this._panelWidth;
+    panelWidth = () => this.layoutDoc && this.layoutDoc.maxWidth ? Math.min(Math.max(NumCast(this.layoutDoc._width), NumCast(this.layoutDoc._nativeWidth)), this._panelWidth) : this._panelWidth;
     panelHeight = () => this._panelHeight;
 
-    nativeWidth = () => !this.layoutDoc!.ignoreAspect && !this.layoutDoc!.fitWidth ? NumCast(this.layoutDoc!.nativeWidth) || this._panelWidth : 0;
-    nativeHeight = () => !this.layoutDoc!.ignoreAspect && !this.layoutDoc!.fitWidth ? NumCast(this.layoutDoc!.nativeHeight) || this._panelHeight : 0;
+    nativeWidth = () => !this.layoutDoc!.ignoreAspect && !this.layoutDoc!._fitWidth ? NumCast(this.layoutDoc!._nativeWidth) || this._panelWidth : 0;
+    nativeHeight = () => !this.layoutDoc!.ignoreAspect && !this.layoutDoc!._fitWidth ? NumCast(this.layoutDoc!._nativeHeight) || this._panelHeight : 0;
 
     contentScaling = () => {
         if (this.layoutDoc!.type === DocumentType.PDF) {
-            if ((this.layoutDoc && this.layoutDoc.fitWidth) ||
-                this._panelHeight / NumCast(this.layoutDoc!.nativeHeight) > this._panelWidth / NumCast(this.layoutDoc!.nativeWidth)) {
-                return this._panelWidth / NumCast(this.layoutDoc!.nativeWidth);
+            if ((this.layoutDoc && this.layoutDoc._fitWidth) ||
+                this._panelHeight / NumCast(this.layoutDoc!._nativeHeight) > this._panelWidth / NumCast(this.layoutDoc!._nativeWidth)) {
+                return this._panelWidth / NumCast(this.layoutDoc!._nativeWidth);
             } else {
-                return this._panelHeight / NumCast(this.layoutDoc!.nativeHeight);
+                return this._panelHeight / NumCast(this.layoutDoc!._nativeHeight);
             }
         }
         const nativeH = this.nativeHeight();
@@ -745,7 +745,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
             (<div className="collectionDockingView-content" ref={ref => this._mainCont = ref}
                 style={{
                     transform: `translate(${this.previewPanelCenteringOffset}px, 0px)`,
-                    height: this.layoutDoc && this.layoutDoc.fitWidth ? undefined : "100%",
+                    height: this.layoutDoc && this.layoutDoc._fitWidth ? undefined : "100%",
                     width: this.widthpercent
                 }}>
                 {this.docView}
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 8bf6b4202..67062ae41 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -38,8 +38,8 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
     componentDidMount() {
         // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking views (masonry isn't yet supported).
-        this._widthDisposer = reaction(() => NumCast(this.props.Document.height, 0) + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0),
-            () => this.props.Document.width = 5 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10),
+        this._widthDisposer = reaction(() => this.props.Document[HeightSym]() + this.childDocs.length + (this.props.Document.isExpanded ? 1 : 0),
+            () => this.props.Document._width = 5 + (this.props.Document.isExpanded ? this.childDocs.length * (this.props.Document[HeightSym]()) : 10),
             { fireImmediately: true }
         );
 
@@ -73,7 +73,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
 
     public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); }
 
-    dimension = () => NumCast(this.props.Document.height); // 2 * the padding
+    dimension = () => NumCast(this.props.Document._height); // 2 * the padding
     getTransform = (ele: React.RefObject<HTMLDivElement>) => () => {
         if (!ele.current) return Transform.Identity();
         const { scale, translateX, translateY } = Utils.GetScreenTransform(ele.current);
@@ -88,11 +88,11 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
                     onChange={action((e: any) => this.props.Document.isExpanded = this.addMenuToggle.current!.checked)} />
                 <label htmlFor={`${guid}`} style={{ marginTop: "auto", marginBottom: "auto", background: StrCast(this.props.Document.backgroundColor, "black") === StrCast(this.props.Document.color, "white") ? "black" : StrCast(this.props.Document.backgroundColor, "black") }} title="Close Menu"><p>+</p></label>
 
-                <div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document.width, 25) }}>
+                <div className="collectionLinearView-content" style={{ height: this.dimension(), width: NumCast(this.props.Document._width, 25) }}>
                     {this.childLayoutPairs.filter((pair) => this.isCurrent(pair.layout)).map((pair, ind) => {
-                        const nested = pair.layout.viewType === CollectionViewType.Linear;
+                        const nested = pair.layout._viewType === CollectionViewType.Linear;
                         const dref = React.createRef<HTMLDivElement>();
-                        const nativeWidth = NumCast(pair.layout.nativeWidth, this.dimension());
+                        const nativeWidth = NumCast(pair.layout._nativeWidth, this.dimension());
                         const deltaSize = nativeWidth * .15 / 2;
                         return <div className={`collectionLinearView-docBtn` + (pair.layout.onClick || pair.layout.onDragStart ? "-scalable" : "")} key={pair.layout[Id]} ref={dref}
                             style={{
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 80752303c..57b091ce4 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -136,7 +136,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     addDocument = (value: string, shiftDown?: boolean) => {
         this._createAliasSelected = false;
         const key = StrCast(this.props.parent.props.Document.sectionFilter);
-        const newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
+        const newDoc = Docs.Create.TextDocument({ _height: 18, _width: 200, title: value });
         newDoc[key] = this.getValue(this.props.heading);
         return this.props.parent.props.addDocument(newDoc);
     }
@@ -258,7 +258,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @computed get contentLayout() {
         const rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
         const style = this.props.parent; const collapsed = this._collapsed;
-        const chromeStatus = this.props.parent.props.Document.chromeStatus;
+        const chromeStatus = this.props.parent.props.Document._chromeStatus;
         const newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
diff --git a/src/client/views/collections/CollectionPivotView.tsx b/src/client/views/collections/CollectionPivotView.tsx
index 43a302af7..a44f990e1 100644
--- a/src/client/views/collections/CollectionPivotView.tsx
+++ b/src/client/views/collections/CollectionPivotView.tsx
@@ -24,11 +24,11 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
         this._narrativeDisposer?.();
     }
     componentDidMount() {
-        this.props.Document.freeformLayoutEngine = "pivot";
-        if (!this.props.Document.facetCollection) {
-            const facetCollection = Docs.Create.TreeDocument([], { title: "facetFilters", yMargin: 0, treeViewHideTitle: true });
+        this.props.Document._freeformLayoutEngine = "pivot";
+        if (!this.props.Document._facetCollection) {
+            const facetCollection = Docs.Create.TreeDocument([], { title: "facetFilters", _yMargin: 0, treeViewHideTitle: true });
             facetCollection.target = this.props.Document;
-            this.props.Document.excludeFields = new List<string>(["facetCollection", "docFilter", "viewSpecScript"]);
+            this.props.Document.excludeFields = new List<string>(["_facetCollection", "_docFilter", "viewSpecScript"]);
 
             const scriptText = "setDocFilter(containingTreeView.target, heading, this.title, checked)";
             const script = CompileScript(scriptText, {
@@ -54,15 +54,10 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
                         }
                     }
                 }), { fireImmediately: true });
-            this.props.Document.facetCollection = facetCollection;
-            this.props.Document.fitToBox = true;
+            this.props.Document._facetCollection = facetCollection;
+            this.props.Document._fitToBox = true;
         }
     }
-
-    @computed get fieldExtensionDoc() {
-        return Doc.fieldExtensionDoc(this.props.DataDoc || this.props.Document, this.props.fieldKey);
-    }
-
     bodyPanelWidth = () => this.props.PanelWidth() - this._facetWidth;
     getTransform = () => this.props.ScreenToLocalTransform().translate(-200, 0);
 
@@ -76,7 +71,7 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
      * Responds to clicking the check box in the flyout menu
      */
     facetClick = (facetHeader: string) => {
-        const facetCollection = this.props.Document.facetCollection;
+        const facetCollection = this.props.Document._facetCollection;
         if (facetCollection instanceof Doc) {
             const found = DocListCast(facetCollection.data).findIndex(doc => doc.title === facetHeader);
             if (found !== -1) {
@@ -120,11 +115,11 @@ export class CollectionPivotView extends CollectionSubView(doc => doc) {
     }
 
     render() {
-        const facetCollection = Cast(this.props.Document?.facetCollection, Doc, null);
+        const facetCollection = Cast(this.props.Document?._facetCollection, Doc, null);
         const flyout = (
             <div className="collectionPivotView-flyout" style={{ width: `${this._facetWidth}` }}>
                 {this._allFacets.map(facet => <label className="collectionPivotView-flyout-item" key={`${facet}`} onClick={e => this.facetClick(facet)}>
-                    <input type="checkbox" onChange={e => { }} checked={this.props.Document.facetCollection instanceof Doc && DocListCast(this.props.Document.facetCollection.data).some(d => {
+                    <input type="checkbox" onChange={e => { }} checked={this.props.Document._facetCollection instanceof Doc && DocListCast(this.props.Document._facetCollection.data).some(d => {
                         return d.title === facet;
                     })} />
                     <span className="checkmark" />
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 994c7b351..9ecb8dc43 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -477,7 +477,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @undoBatch
     createRow = () => {
-        const newDoc = Docs.Create.TextDocument({ title: "", width: 100, height: 30 });
+        const newDoc = Docs.Create.TextDocument({ title: "", _width: 100, _height: 30 });
         this.props.addDocument(newDoc);
     }
 
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ec22bb813..372db5fee 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -39,13 +39,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
-    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => !pair.layout.isMinimized).map(pair => pair.layout); }
-    @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
-    @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document.yMargin, 2 * this.gridGap)); }
-    @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
+    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.isMinimized).map(pair => pair.layout); }
+    @computed get xMargin() { return NumCast(this.props.Document._xMargin, 2 * this.gridGap); }
+    @computed get yMargin() { return Math.max(this.props.Document.showTitle && !this.props.Document.showTitleHover ? 30 : 0, NumCast(this.props.Document._yMargin, 2 * this.gridGap)); }
+    @computed get gridGap() { return NumCast(this.props.Document._gridGap, 10); }
     @computed get isStackingView() { return BoolCast(this.props.Document.singleColumn, true); }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
-    @computed get showAddAGroup() { return (this.sectionFilter && (this.props.Document.chromeStatus !== 'view-mode' && this.props.Document.chromeStatus !== 'disabled')); }
+    @computed get showAddAGroup() { return (this.sectionFilter && (this.props.Document._chromeStatus !== 'view-mode' && this.props.Document._chromeStatus !== 'disabled')); }
     @computed get columnWidth() {
         return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin,
             this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250));
@@ -55,7 +55,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     children(docs: Doc[]) {
         this._docXfs.length = 0;
         return docs.map((d, i) => {
-            const width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
+            const width = () => Math.min(d._nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
             const height = () => this.getDocHeight(d);
             const dref = React.createRef<HTMLDivElement>();
             const dxf = () => this.getDocTransform(d, dref.current!);
@@ -125,7 +125,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         },
             (hgt: number) => {
                 const doc = hgt === -1 ? undefined : this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc;
-                doc && hgt > 0 && (Doc.Layout(doc).height = hgt);
+                doc && hgt > 0 && (Doc.Layout(doc)._height = hgt);
             },
             { fireImmediately: true }
         );
@@ -187,16 +187,16 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     getDocHeight(d?: Doc) {
         if (!d) return 0;
         const layoutDoc = Doc.Layout(d);
-        const nw = NumCast(layoutDoc.nativeWidth);
-        const nh = NumCast(layoutDoc.nativeHeight);
+        const nw = NumCast(layoutDoc._nativeWidth);
+        const nh = NumCast(layoutDoc._nativeHeight);
         let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
-        if (!layoutDoc.ignoreAspect && !layoutDoc.fitWidth && nw && nh) {
+        if (!layoutDoc.ignoreAspect && !layoutDoc._fitWidth && nw && nh) {
             const aspect = nw && nh ? nh / nw : 1;
-            if (!(d.nativeWidth && !layoutDoc.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(layoutDoc[WidthSym](), wid);
+            if (!(d._nativeWidth && !layoutDoc.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(layoutDoc[WidthSym](), wid);
             return wid * aspect;
         }
-        return layoutDoc.fitWidth ? !layoutDoc.nativeHeight ? this.props.PanelHeight() - 2 * this.yMargin :
-            Math.min(wid * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc.nativeHeight)) / NumCast(layoutDoc.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : layoutDoc[HeightSym]();
+        return layoutDoc._fitWidth ? !layoutDoc._nativeHeight ? this.props.PanelHeight() - 2 * this.yMargin :
+            Math.min(wid * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : layoutDoc[HeightSym]();
     }
 
     columnDividerDown = (e: React.PointerEvent) => {
@@ -241,7 +241,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 const pos1 = cd.dxf().inverse().transformPoint(cd.width(), cd.height());
                 if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
                     targInd = i;
-                    const axis = this.Document.viewType === CollectionViewType.Masonry ? 0 : 1;
+                    const axis = this.Document._viewType === CollectionViewType.Masonry ? 0 : 1;
                     plusOne = where[axis] > (pos[axis] + pos1[axis]) / 2 ? 1 : 0;
                 }
             });
@@ -359,7 +359,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
 
     onToggle = (checked: Boolean) => {
-        this.props.Document.chromeStatus = checked ? "collapsed" : "view-mode";
+        this.props.Document._chromeStatus = checked ? "collapsed" : "view-mode";
     }
 
     onContextMenu = (e: React.MouseEvent): void => {
@@ -408,10 +408,10 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                             style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
                             <EditableView {...editableViewProps} />
                         </div>}
-                    {this.props.Document.chromeStatus !== 'disabled' ? <Switch
+                    {this.props.Document._chromeStatus !== 'disabled' ? <Switch
                         onChange={this.onToggle}
                         onClick={this.onToggle}
-                        defaultChecked={this.props.Document.chromeStatus !== 'view-mode'}
+                        defaultChecked={this.props.Document._chromeStatus !== 'view-mode'}
                         checkedChildren="edit"
                         unCheckedChildren="view"
                     /> : null}
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index f0dcadb5b..29dfb60c5 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -136,7 +136,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @action
     addDocument = (value: string, shiftDown?: boolean) => {
         if (value === ":freeForm") {
-            return this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { width: 200, height: 200 }));
+            return this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { _width: 200, _height: 200 }));
         } else if (value.startsWith(":")) {
             const { Document, addDocument } = this.props.parent.props;
             const fieldKey = value.substring(1);
@@ -152,7 +152,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         }
         this._createAliasSelected = false;
         const key = StrCast(this.props.parent.props.Document.sectionFilter);
-        const newDoc = Docs.Create.TextDocument({ height: 18, width: 200, documentText: "@@@" + value, title: value, autoHeight: true });
+        const newDoc = Docs.Create.TextDocument({ _height: 18, _width: 200, documentText: "@@@" + value, title: value, autoHeight: true });
         newDoc[key] = this.getValue(this.props.heading);
         const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
         const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
@@ -310,7 +310,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                 style={{
                     width: (style.columnWidth) /
                         ((uniqueHeadings.length +
-                            ((this.props.parent.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
+                            ((this.props.parent.props.Document._chromeStatus !== 'view-mode' && this.props.parent.props.Document._chromeStatus !== 'disabled') ? 1 : 0)) || 1)
                 }}>
                 <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
@@ -350,7 +350,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                 </div>
             </div> : (null);
         for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
-        const chromeStatus = this.props.parent.props.Document.chromeStatus;
+        const chromeStatus = this.props.parent.props.Document._chromeStatus;
         return (
             <div className="collectionStackingViewFieldColumn" key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
                 ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
diff --git a/src/client/views/collections/CollectionStaffView.tsx b/src/client/views/collections/CollectionStaffView.tsx
index 105061f46..8c7e113b2 100644
--- a/src/client/views/collections/CollectionStaffView.tsx
+++ b/src/client/views/collections/CollectionStaffView.tsx
@@ -23,10 +23,6 @@ export class CollectionStaffView extends CollectionSubView(doc => doc) {
         this.props.Document.staves = 5;
     }
 
-    @computed get fieldExtensionDoc() {
-        return Doc.fieldExtensionDoc(this.props.DataDoc || this.props.Document, this.props.fieldKey);
-    }
-
     @computed get addStaffButton() {
         return <div onPointerDown={this.addStaff}>+</div>;
     }
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 063b5c5df..db393918d 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -82,7 +82,6 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         }
 
         @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) : Doc.GetProto(this.props.Document); }
-        @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
 
         // The data field for rendering this collection will be on the this.props.Document unless we're rendering a template in which case we try to use props.DataDoc.
         // When a document has a DataDoc but it's not a template, then it contains its own rendering data, but needs to pass the DataDoc through
@@ -90,14 +89,10 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
         // If 'annotationField' is specified, then all children exist on that field of the extension document, otherwise, they exist directly on the data document under 'fieldKey'
         @computed get dataField() {
             const { annotationsKey, fieldKey } = this.props;
-            const { extensionDoc, dataDoc } = this;
             if (annotationsKey) {
-                if (extensionDoc) {
-                    return extensionDoc[annotationsKey];
-                }
-                return undefined;
+                return this.dataDoc[fieldKey + "-" + annotationsKey];
             }
-            return dataDoc[fieldKey];
+            return this.dataDoc[fieldKey];
         }
 
         get childLayoutPairs(): { layout: Doc; data: Doc; }[] {
@@ -216,7 +211,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                         this.props.addDocument && this.props.addDocument(Docs.Create.WebDocument(href, { ...options, title: href }));
                     }
                 } else if (text) {
-                    this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text }));
+                    this.props.addDocument && this.props.addDocument(Docs.Create.TextDocument({ ...options, _width: 100, _height: 25, documentText: "@@@" + text }));
                 }
                 return;
             }
@@ -226,7 +221,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 const img = tags[0].startsWith("img") ? tags[0] : tags.length > 1 && tags[1].startsWith("img") ? tags[1] : "";
                 if (img) {
                     const split = img.split("src=\"")[1].split("\"")[0];
-                    const doc = Docs.Create.ImageDocument(split, { ...options, width: 300 });
+                    const doc = Docs.Create.ImageDocument(split, { ...options, _width: 300 });
                     ImageUtils.ExtractExif(doc);
                     this.props.addDocument(doc);
                     return;
@@ -241,7 +236,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                             }
                         });
                     } else {
-                        const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", width: 300, height: 300, documentText: text });
+                        const htmlDoc = Docs.Create.HtmlDocument(html, { ...options, title: "-web page-", _width: 300, _height: 300, documentText: text });
                         this.props.addDocument(htmlDoc);
                     }
                     return;
@@ -249,12 +244,12 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             }
             if (text && text.indexOf("www.youtube.com/watch") !== -1) {
                 const url = text.replace("youtube.com/watch?v=", "youtube.com/embed/");
-                this.props.addDocument(Docs.Create.VideoDocument(url, { ...options, title: url, width: 400, height: 315, nativeWidth: 600, nativeHeight: 472.5 }));
+                this.props.addDocument(Docs.Create.VideoDocument(url, { ...options, title: url, _width: 400, _height: 315, _nativeWidth: 600, _nativeHeight: 472.5 }));
                 return;
             }
             let matches: RegExpExecArray | null;
             if ((matches = /(https:\/\/)?docs\.google\.com\/document\/d\/([^\\]+)\/edit/g.exec(text)) !== null) {
-                const newBox = Docs.Create.TextDocument({ ...options, width: 400, height: 200, title: "Awaiting title from Google Docs..." });
+                const newBox = Docs.Create.TextDocument({ ...options, _width: 400, _height: 200, title: "Awaiting title from Google Docs..." });
                 const proto = newBox.proto!;
                 const documentId = matches[2];
                 proto[GoogleRef] = documentId;
@@ -303,7 +298,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                     const dropFileName = file ? file.name : "-empty-";
                     promises.push(Networking.PostFormDataToServer("/upload", formData).then(results => {
                         results.map(action(({ clientAccessPath }: any) => {
-                            const full = { ...options, width: 300, title: dropFileName };
+                            const full = { ...options, _width: 300, title: dropFileName };
                             const pathname = Utils.prepend(clientAccessPath);
                             Docs.Get.DocumentFromType(type, pathname, full).then(doc => {
                                 doc && (Doc.GetProto(doc).fileUpload = basename(pathname).replace("upload_", "").replace(/\.[a-z0-9]*$/, ""));
@@ -318,7 +313,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                 Promise.all(promises).finally(() => { completed && completed(); batch.end(); });
             } else {
                 if (text && !text.includes("https://")) {
-                    this.props.addDocument(Docs.Create.TextDocument({ ...options, documentText: "@@@" + text, width: 400, height: 315 }));
+                    this.props.addDocument(Docs.Create.TextDocument({ ...options, documentText: "@@@" + text, _width: 400, _height: 315 }));
                 }
                 batch.end();
             }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ec348e74b..21f2bc326 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -179,7 +179,7 @@ class TreeView extends React.Component<TreeViewProps> {
         OnFillDown={undoBatch((value: string) => {
             Doc.SetInPlace(this.props.document, key, value, false);
             const layoutDoc = this.props.document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.document.layoutCustom)) : undefined;
-            const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+            const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
             TreeView.loadId = doc[Id];
             return this.props.addDocument(doc);
         })}
@@ -210,7 +210,7 @@ class TreeView extends React.Component<TreeViewProps> {
                 ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
                 ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
             }
-            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
+            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { const kvp = Docs.Create.KVPDocument(this.props.document, { _width: 300, _height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
             ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" });
             ContextMenu.Instance.displayMenu(e.pageX > 156 ? e.pageX - 156 : 0, e.pageY - 15);
             e.stopPropagation();
@@ -256,21 +256,21 @@ class TreeView extends React.Component<TreeViewProps> {
     }
     docWidth = () => {
         const layoutDoc = Doc.Layout(this.props.document);
-        const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth);
+        const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth);
         if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.panelWidth() - 20));
-        return NumCast(layoutDoc.nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
+        return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.panelWidth() - 20) : this.props.panelWidth() - 20;
     }
     docHeight = () => {
         const layoutDoc = Doc.Layout(this.props.document);
         const bounds = this.boundsOfCollectionDocument;
         return Math.min(this.MAX_EMBED_HEIGHT, (() => {
-            const aspect = NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth, 1);
+            const aspect = NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth, 1);
             if (aspect) return this.docWidth() * aspect;
             if (bounds) return this.docWidth() * (bounds.b - bounds.y) / (bounds.r - bounds.x);
-            return layoutDoc.fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection.height) :
-                Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc.nativeHeight)) / NumCast(layoutDoc.nativeWidth,
-                    NumCast(this.props.containingCollection.height)))) :
-                NumCast(layoutDoc.height) ? NumCast(layoutDoc.height) : 50;
+            return layoutDoc._fitWidth ? (!this.props.document.nativeHeight ? NumCast(this.props.containingCollection._height) :
+                Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+                    NumCast(this.props.containingCollection._height)))) :
+                NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
         })());
     }
 
@@ -547,7 +547,7 @@ class TreeView extends React.Component<TreeViewProps> {
             };
             const childLayout = Doc.Layout(pair.layout);
             const rowHeight = () => {
-                const aspect = NumCast(childLayout.nativeWidth, 0) / NumCast(childLayout.nativeHeight, 0);
+                const aspect = NumCast(childLayout._nativeWidth, 0) / NumCast(childLayout._nativeHeight, 0);
                 return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
             };
             return !(child instanceof Doc) ? (null) : <TreeView
@@ -637,10 +637,10 @@ export class CollectionTreeView extends CollectionSubView(Document) {
 
                 const detailedLayout = Docs.Create.StackingDocument([
                     ImageDocument(fallbackImg, { title: "activeHero" }),
-                    TreeDocument([], { title: "data", height: 100, onChildClick: ScriptField.MakeFunction(`containingCollection.resolvedDataDoc.activeHero = copyField(this.data)`, { containingCollection: Doc.name }) }),
+                    MulticolumnDocument([], { title: "data", _height: 100, onChildClick: ScriptField.MakeFunction(`containingCollection.resolvedDataDoc.activeHero = copyField(this.data)`, { containingCollection: Doc.name }) }),
                     TextDocument({ title: "short_description", autoHeight: true }),
-                    ...["year", "company", "degrees_of_freedom"].map(key => TextDocument({ title: key, height: 30 }))
-                ], { autoHeight: true, chromeStatus: "disabled", title: "detailed layout stack" });
+                    ...["year", "company", "degrees_of_freedom"].map(key => TextDocument({ title: key, _height: 30 }))
+                ], { autoHeight: true, _chromeStatus: "disabled", title: "detailed layout stack" });
                 detailedLayout.isTemplateDoc = makeTemplate(detailedLayout);
 
                 const cardLayout = ImageDocument(fallbackImg, { isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
@@ -650,7 +650,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
 
                 Document.childLayout = cardLayout;
                 Document.childDetailed = detailedLayout;
-                Document.viewType = CollectionViewType.Pivot;
+                Document._viewType = CollectionViewType.Pivot;
                 Document.pivotField = "company";
             }
         });
@@ -675,12 +675,12 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
 
     render() {
-        const dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
+        const dropAction = StrCast(this.props.Document._dropAction) as dropActionType;
         const addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
         const moveDoc = (d: Doc, target: Doc | undefined, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
         return !this.childDocs ? (null) : (
             <div className="collectionTreeView-dropTarget" id="body"
-                style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document.yMargin, 20)}px` }}
+                style={{ background: StrCast(this.props.Document.backgroundColor, "lightgray"), paddingTop: `${NumCast(this.props.Document._yMargin, 20)}px` }}
                 onContextMenu={this.onContextMenu}
                 onWheel={(e: React.WheelEvent) => this._mainEle && this._mainEle.scrollHeight > this._mainEle.clientHeight && e.stopPropagation()}
                 onDrop={this.onTreeDrop}
@@ -695,7 +695,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
                     OnFillDown={undoBatch((value: string) => {
                         Doc.SetInPlace(this.dataDoc, "title", value, false);
                         const layoutDoc = this.props.Document.layoutCustom instanceof Doc ? Doc.ApplyTemplate(Doc.GetProto(this.props.Document.layoutCustom)) : undefined;
-                        const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25, templates: new List<string>([Templates.Title.Layout]) });
+                        const doc = layoutDoc || Docs.Create.FreeformDocument([], { title: "", x: 0, y: 0, _width: 100, _height: 25, templates: new List<string>([Templates.Title.Layout]) });
                         TreeView.loadId = doc[Id];
                         Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, this.childDocs.length ? this.childDocs[0] : undefined, true, false, false, false);
                     })} />)}
@@ -734,7 +734,7 @@ Scripting.addGlobal(function readFacetData(layoutDoc: Doc, dataDoc: Doc, dataKey
 });
 
 Scripting.addGlobal(function determineCheckedState(layoutDoc: Doc, facetHeader: string, facetValue: string) {
-    const docFilters = Cast(layoutDoc.docFilter, listSpec("string"), []);
+    const docFilters = Cast(layoutDoc._docFilter, listSpec("string"), []);
     for (let i = 0; i < docFilters.length; i += 3) {
         const [header, value, state] = docFilters.slice(i, i + 3);
         if (header === facetHeader && value === facetValue) {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 430aecef4..715094bf5 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -91,17 +91,8 @@ export class CollectionView extends Touchable<FieldViewProps> {
     @observable private static _safeMode = false;
     public static SetSafeMode(safeMode: boolean) { this._safeMode = safeMode; }
 
-    @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.props.Document, this.props.fieldKey); }
-
     get collectionViewType(): CollectionViewType | undefined {
-        if (!this.extensionDoc) return CollectionViewType.Invalid;
-        NumCast(this.props.Document.viewType) && setTimeout(() => {
-            if (this.props.Document.viewType) {
-                this.extensionDoc!.viewType = NumCast(this.props.Document.viewType);
-            }
-            Doc.GetProto(this.props.Document).viewType = this.props.Document.viewType = undefined;
-        });
-        const viewField = NumCast(this.extensionDoc.viewType, Cast(this.props.Document.viewType, "number"));
+        const viewField = NumCast(this.props.Document._viewType);
         if (CollectionView._safeMode) {
             if (viewField === CollectionViewType.Freeform) {
                 return CollectionViewType.Tree;
@@ -110,15 +101,15 @@ export class CollectionView extends Touchable<FieldViewProps> {
                 return CollectionViewType.Freeform;
             }
         }
-        return viewField === undefined ? CollectionViewType.Invalid : viewField;
+        return viewField;
     }
 
     componentDidMount = () => {
-        this._reactionDisposer = reaction(() => StrCast(this.props.Document.chromeStatus),
+        this._reactionDisposer = reaction(() => StrCast(this.props.Document._chromeStatus),
             () => {
                 // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
                 // chrome status may also be view-mode, in reference to stacking view's toggle mode. it is essentially disabled mode, but prevents the toggle button from showing up on the left sidebar.
-                const chromeStatus = this.props.Document.chromeStatus;
+                const chromeStatus = this.props.Document._chromeStatus;
                 if (chromeStatus && (chromeStatus === "disabled" || chromeStatus === "collapsed")) {
                     runInAction(() => this._collapsed = true);
                 }
@@ -128,7 +119,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     componentWillUnmount = () => this._reactionDisposer && this._reactionDisposer();
 
     // bcz: Argh?  What's the height of the collection chromes??  
-    chromeHeight = () => (this.props.Document.chromeStatus === "enabled" ? -60 : 0);
+    chromeHeight = () => (this.props.Document._chromeStatus === "enabled" ? -60 : 0);
 
     active = (outsideReaction?: boolean) => this.props.isSelected(outsideReaction) || BoolCast(this.props.Document.forceActive) || this._isChildActive || this.props.renderDepth === 0;
 
@@ -138,8 +129,7 @@ export class CollectionView extends Touchable<FieldViewProps> {
     addDocument(doc: Doc): boolean {
         const targetDataDoc = Doc.GetProto(this.props.Document);
         Doc.AddDocToList(targetDataDoc, this.props.fieldKey, doc);
-        const extension = Doc.fieldExtensionDoc(targetDataDoc, this.props.fieldKey);  // set metadata about the field being rendered (ie, the set of documents) on an extension field for that field
-        extension && (extension.lastModified = new DateField(new Date(Date.now())));
+        targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
         Doc.GetProto(doc).lastOpened = new DateField;
         return true;
     }
@@ -192,19 +182,19 @@ export class CollectionView extends Touchable<FieldViewProps> {
             case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView key="collview" {...props} />); }
             case CollectionViewType.Pivot: { return (<CollectionPivotView key="collview" {...props} />); }
             case CollectionViewType.Freeform:
-            default: { this.props.Document.freeformLayoutEngine = undefined; return (<CollectionFreeFormView key="collview" {...props} />); }
+            default: { this.props.Document._freeformLayoutEngine = undefined; return (<CollectionFreeFormView key="collview" {...props} />); }
         }
     }
 
     @action
     private collapse = (value: boolean) => {
         this._collapsed = value;
-        this.props.Document.chromeStatus = value ? "collapsed" : "enabled";
+        this.props.Document._chromeStatus = value ? "collapsed" : "enabled";
     }
 
     private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
-        const chrome = this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking ? (null) :
+        const chrome = this.props.Document._chromeStatus === "disabled" || type === CollectionViewType.Docking ? (null) :
             <CollectionViewBaseChrome CollectionView={this} key="chrome" type={type} collapse={this.collapse} />;
         return [chrome, this.SubViewHelper(type, renderProps)];
     }
@@ -214,24 +204,24 @@ export class CollectionView extends Touchable<FieldViewProps> {
         if (!e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
             const existingVm = ContextMenu.Instance.findByDescription("View Modes...");
             const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
-            subItems.push({ description: "Freeform", event: () => { this.props.Document.viewType = CollectionViewType.Freeform; }, icon: "signature" });
+            subItems.push({ description: "Freeform", event: () => { this.props.Document._viewType = CollectionViewType.Freeform; }, icon: "signature" });
             if (CollectionView._safeMode) {
-                ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => this.props.Document.viewType = CollectionViewType.Invalid, icon: "project-diagram" });
+                ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => this.props.Document._viewType = CollectionViewType.Invalid, icon: "project-diagram" });
             }
-            subItems.push({ description: "Schema", event: () => this.props.Document.viewType = CollectionViewType.Schema, icon: "th-list" });
-            subItems.push({ description: "Treeview", event: () => this.props.Document.viewType = CollectionViewType.Tree, icon: "tree" });
-            subItems.push({ description: "Stacking", event: () => this.props.Document.viewType = CollectionViewType.Stacking, icon: "ellipsis-v" });
+            subItems.push({ description: "Schema", event: () => this.props.Document._viewType = CollectionViewType.Schema, icon: "th-list" });
+            subItems.push({ description: "Treeview", event: () => this.props.Document._viewType = CollectionViewType.Tree, icon: "tree" });
+            subItems.push({ description: "Stacking", event: () => this.props.Document._viewType = CollectionViewType.Stacking, icon: "ellipsis-v" });
             subItems.push({
                 description: "Stacking (AutoHeight)", event: () => {
-                    this.props.Document.viewType = CollectionViewType.Stacking;
+                    this.props.Document._viewType = CollectionViewType.Stacking;
                     this.props.Document.autoHeight = true;
                 }, icon: "ellipsis-v"
             });
-            subItems.push({ description: "Staff", event: () => this.props.Document.viewType = CollectionViewType.Staff, icon: "music" });
-            subItems.push({ description: "Multicolumn", event: () => this.props.Document.viewType = CollectionViewType.Multicolumn, icon: "columns" });
-            subItems.push({ description: "Masonry", event: () => this.props.Document.viewType = CollectionViewType.Masonry, icon: "columns" });
-            subItems.push({ description: "Pivot", event: () => this.props.Document.viewType = CollectionViewType.Pivot, icon: "columns" });
-            switch (this.props.Document.viewType) {
+            subItems.push({ description: "Staff", event: () => this.props.Document._viewType = CollectionViewType.Staff, icon: "music" });
+            subItems.push({ description: "Multicolumn", event: () => this.props.Document._viewType = CollectionViewType.Multicolumn, icon: "columns" });
+            subItems.push({ description: "Masonry", event: () => this.props.Document._viewType = CollectionViewType.Masonry, icon: "columns" });
+            subItems.push({ description: "Pivot", event: () => this.props.Document._viewType = CollectionViewType.Pivot, icon: "columns" });
+            switch (this.props.Document._viewType) {
                 case CollectionViewType.Freeform: {
                     subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
                     break;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 42c563fe2..59d7a2671 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -55,9 +55,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         immediate: (draggedDocs: Doc[]) => Doc.GetProto(this.props.CollectionView.props.Document).data = new List<Doc>(draggedDocs.map((d: any) => Doc.MakeAlias(d)))
     };
     _viewCommand = {
-        title: "restore view", script: "this.target.panX = this.restoredPanX; this.target.panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"],
-        immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document.panX = 0; this.props.CollectionView.props.Document.panY = 0; this.props.CollectionView.props.Document.scale = 1; },
-        initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document.panX; button.restoredPanY = this.props.CollectionView.props.Document.panY; button.restoredScale = this.props.CollectionView.props.Document.scale; }
+        title: "restore view", script: "this.target._panX = this.restoredPanX; this.target._panY = this.restoredPanY; this.target.scale = this.restoredScale;", params: ["target"],
+        immediate: (draggedDocs: Doc[]) => { this.props.CollectionView.props.Document._panX = 0; this.props.CollectionView.props.Document._panY = 0; this.props.CollectionView.props.Document.scale = 1; },
+        initialize: (button: Doc) => { button.restoredPanX = this.props.CollectionView.props.Document._panX; button.restoredPanY = this.props.CollectionView.props.Document._panY; button.restoredScale = this.props.CollectionView.props.Document.scale; }
     };
     _freeform_commands = [this._contentCommand, this._templateCommand, this._narrativeCommand, this._viewCommand];
     _stacking_commands = [this._contentCommand, this._templateCommand];
@@ -132,7 +132,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         runInAction(() => {
             this.addKeyRestrictions(fields);
             // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
-            const chromeStatus = this.props.CollectionView.props.Document.chromeStatus;
+            const chromeStatus = this.props.CollectionView.props.Document._chromeStatus;
             if (chromeStatus) {
                 if (chromeStatus === "disabled") {
                     throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
@@ -149,7 +149,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     @undoBatch
     viewChanged = (e: React.ChangeEvent) => {
         //@ts-ignore
-        this.props.CollectionView.props.Document.viewType = parseInt(e.target.selectedOptions[0].value);
+        this.props.CollectionView.props.Document._viewType = parseInt(e.target.selectedOptions[0].value);
     }
 
     @action
@@ -223,7 +223,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             `(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
             "true";
 
-        const docFilter = Cast(this.props.CollectionView.props.Document.docFilter, listSpec("string"), []);
+        const docFilter = Cast(this.props.CollectionView.props.Document._docFilter, listSpec("string"), []);
         const docFilterText = Doc.MakeDocFilter(docFilter);
         const finalScript = docFilterText && !fullScript.startsWith("(())") ? `${fullScript} ${docFilterText ? "&&" : ""} (${docFilterText})` :
             docFilterText ? docFilterText : fullScript;
@@ -242,9 +242,9 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     @action
     toggleCollapse = () => {
-        this.props.CollectionView.props.Document.chromeStatus = this.props.CollectionView.props.Document.chromeStatus === "enabled" ? "collapsed" : "enabled";
+        this.props.CollectionView.props.Document._chromeStatus = this.props.CollectionView.props.Document._chromeStatus === "enabled" ? "collapsed" : "enabled";
         if (this.props.collapse) {
-            this.props.collapse(this.props.CollectionView.props.Document.chromeStatus !== "enabled");
+            this.props.collapse(this.props.CollectionView.props.Document._chromeStatus !== "enabled");
         }
     }
 
@@ -272,7 +272,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     @observable private pivotKeyDisplay = this.pivotKey;
     getPivotInput = () => {
-        if (StrCast(this.document.freeformLayoutEngine) !== "pivot") {
+        if (StrCast(this.document._freeformLayoutEngine) !== "pivot") {
             return (null);
         }
         return (<input className="collectionViewBaseChrome-viewSpecsInput"
@@ -383,7 +383,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     }
 
     render() {
-        const collapsed = this.props.CollectionView.props.Document.chromeStatus !== "enabled";
+        const collapsed = this.props.CollectionView.props.Document._chromeStatus !== "enabled";
         return (
             <div className="collectionViewChrome-cont" style={{ top: collapsed ? -70 : 0, height: collapsed ? 0 : undefined }}>
                 <div className="collectionViewChrome">
@@ -402,7 +402,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                             className="collectionViewBaseChrome-viewPicker"
                             onPointerDown={stopPropagation}
                             onChange={this.viewChanged}
-                            value={NumCast(this.props.CollectionView.props.Document.viewType)}>
+                            value={NumCast(this.props.CollectionView.props.Document._viewType)}>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
diff --git a/src/client/views/collections/ParentDocumentSelector.tsx b/src/client/views/collections/ParentDocumentSelector.tsx
index 1cc05f92c..18f1baf44 100644
--- a/src/client/views/collections/ParentDocumentSelector.tsx
+++ b/src/client/views/collections/ParentDocumentSelector.tsx
@@ -21,7 +21,13 @@ export const Flyout = higflyout.default;
 
 library.add(faEdit);
 
-type SelectorProps = { Document: Doc, Views: DocumentView[], Stack?: any, addDocTab(doc: Doc, dataDoc: Doc | undefined, location: string): void };
+type SelectorProps = {
+    Document: Doc,
+    Views: DocumentView[],
+    Stack?: any,
+    addDocTab(doc: Doc, dataDoc: Doc | undefined, location: string): void
+};
+
 @observer
 export class SelectorContextMenu extends React.Component<SelectorProps> {
     @observable private _docs: { col: Doc, target: Doc }[] = [];
@@ -49,11 +55,11 @@ export class SelectorContextMenu extends React.Component<SelectorProps> {
     getOnClick({ col, target }: { col: Doc, target: Doc }) {
         return () => {
             col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
-            if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
-                const newPanX = NumCast(target.x) + NumCast(target.width) / 2;
-                const newPanY = NumCast(target.y) + NumCast(target.height) / 2;
-                col.panX = newPanX;
-                col.panY = newPanY;
+            if (NumCast(col._viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
+                const newPanX = NumCast(target.x) + NumCast(target._width) / 2;
+                const newPanY = NumCast(target.y) + NumCast(target._height) / 2;
+                col._panX = newPanX;
+                col._panY = newPanY;
             }
             this.props.addDocTab(col, undefined, "inTab"); // bcz: dataDoc?
         };
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 32097816d..8bf56338b 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -79,10 +79,10 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
         for (const doc of val) {
             const layoutDoc = Doc.Layout(doc);
             let wid = pivotAxisWidth;
-            let hgt = layoutDoc.nativeWidth ? (NumCast(layoutDoc.nativeHeight) / NumCast(layoutDoc.nativeWidth)) * pivotAxisWidth : pivotAxisWidth;
+            let hgt = layoutDoc._nativeWidth ? (NumCast(layoutDoc._nativeHeight) / NumCast(layoutDoc._nativeWidth)) * pivotAxisWidth : pivotAxisWidth;
             if (hgt > pivotAxisWidth) {
                 hgt = pivotAxisWidth;
-                wid = layoutDoc.nativeHeight ? (NumCast(layoutDoc.nativeWidth) / NumCast(layoutDoc.nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
+                wid = layoutDoc.nativeHeight ? (NumCast(layoutDoc._nativeWidth) / NumCast(layoutDoc._nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
             }
             docMap.set(doc, {
                 x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2 + (val.length < numCols ? (numCols - val.length) * pivotAxisWidth / 2 : 0),
@@ -104,8 +104,8 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
             x: NumCast(pair.layout.x),
             y: NumCast(pair.layout.y),
             z: NumCast(pair.layout.z),
-            width: NumCast(pair.layout.width),
-            height: NumCast(pair.layout.height)
+            width: NumCast(pair.layout._width),
+            height: NumCast(pair.layout._height)
         };
         const pos = docMap.get(pair.layout) || defaultPosition;
         const data = poolData.get(pair.layout[Id]);
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 65953dbdc..c89fb92a5 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -41,15 +41,13 @@ import React = require("react");
 import { computedFn } from "mobx-utils";
 import { TraceMobx } from "../../../../new_fields/util";
 import { GestureUtils } from "../../../../pen-gestures/GestureUtils";
-import { LinkManager } from "../../../util/LinkManager";
 import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
-import CollectionPaletteVIew from "../../Palette";
 
 library.add(faEye as any, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass, faUpload, faBraille, faChalkboard, faFileUpload);
 
 export const panZoomSchema = createSchema({
-    panX: "number",
-    panY: "number",
+    _panX: "number",
+    _panY: "number",
     scale: "number",
     arrangeScript: ScriptField,
     arrangeInit: ScriptField,
@@ -81,16 +79,16 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     @observable.shallow _layoutElements: ViewDefResult[] = []; // shallow because some layout items (eg pivot labels) are just generated 'divs' and can't be frozen as observables
     @observable _clusterSets: (Doc[])[] = [];
 
-    @computed get fitToContent() { return (this.props.fitToBox || this.Document.fitToBox) && !this.isAnnotationOverlay; }
+    @computed get fitToContent() { return (this.props.fitToBox || this.Document._fitToBox) && !this.isAnnotationOverlay; }
     @computed get parentScaling() { return this.props.ContentScaling && this.fitToContent && !this.isAnnotationOverlay ? this.props.ContentScaling() : 1; }
     @computed get contentBounds() { return aggregateBounds(this._layoutElements.filter(e => e.bounds && !e.bounds.z).map(e => e.bounds!), NumCast(this.layoutDoc.xPadding, 10), NumCast(this.layoutDoc.yPadding, 10)); }
-    @computed get nativeWidth() { return this.Document.fitToContent ? 0 : this.Document.nativeWidth || 0; }
-    @computed get nativeHeight() { return this.fitToContent ? 0 : this.Document.nativeHeight || 0; }
+    @computed get nativeWidth() { return this.Document._fitToContent ? 0 : this.Document._nativeWidth || 0; }
+    @computed get nativeHeight() { return this.fitToContent ? 0 : this.Document._nativeHeight || 0; }
     private get isAnnotationOverlay() { return this.props.isAnnotationOverlay; }
     private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
     private easing = () => this.props.Document.panTransformType === "Ease";
-    private panX = () => this.fitToContent ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document.panX || 0;
-    private panY = () => this.fitToContent ? (this.contentBounds.y + this.contentBounds.b) / 2 : this.Document.panY || 0;
+    private panX = () => this.fitToContent ? (this.contentBounds.x + this.contentBounds.r) / 2 : this.Document._panX || 0;
+    private panY = () => this.fitToContent ? (this.contentBounds.y + this.contentBounds.b) / 2 : this.Document._panY || 0;
     private zoomScaling = () => (1 / this.parentScaling) * (this.fitToContent ?
         Math.min(this.props.PanelHeight() / (this.contentBounds.b - this.contentBounds.y), this.props.PanelWidth() / (this.contentBounds.r - this.contentBounds.x)) :
         this.Document.scale || 1)
@@ -146,13 +144,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                         const layoutDoc = Doc.Layout(d);
                         d.x = x + NumCast(d.x) - dropX;
                         d.y = y + NumCast(d.y) - dropY;
-                        if (!NumCast(layoutDoc.width)) {
-                            layoutDoc.width = 300;
+                        if (!NumCast(layoutDoc._width)) {
+                            layoutDoc._width = 300;
                         }
-                        if (!NumCast(layoutDoc.height)) {
-                            const nw = NumCast(layoutDoc.nativeWidth);
-                            const nh = NumCast(layoutDoc.nativeHeight);
-                            layoutDoc.height = nw && nh ? nh / nw * NumCast(layoutDoc.width) : 300;
+                        if (!NumCast(layoutDoc._height)) {
+                            const nw = NumCast(layoutDoc._nativeWidth);
+                            const nh = NumCast(layoutDoc._nativeHeight);
+                            layoutDoc._height = nw && nh ? nh / nw * NumCast(layoutDoc._width) : 300;
                         }
                         this.bringToFront(d);
                     }));
@@ -182,8 +180,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             const layoutDoc = Doc.Layout(cd);
             const cx = NumCast(cd.x) - this._clusterDistance;
             const cy = NumCast(cd.y) - this._clusterDistance;
-            const cw = NumCast(layoutDoc.width) + 2 * this._clusterDistance;
-            const ch = NumCast(layoutDoc.height) + 2 * this._clusterDistance;
+            const cw = NumCast(layoutDoc._width) + 2 * this._clusterDistance;
+            const ch = NumCast(layoutDoc._height) + 2 * this._clusterDistance;
             return !layoutDoc.z && intersectRect({ left: cx, top: cy, width: cw, height: ch }, { left: probe[0], top: probe[1], width: 1, height: 1 }) ?
                 NumCast(cd.cluster) : cluster;
         }, -1);
@@ -353,7 +351,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             case GestureUtils.Gestures.Stroke:
                 const points = ge.points;
                 const B = this.getTransform().transformBounds(ge.bounds.left, ge.bounds.top, ge.bounds.width, ge.bounds.height);
-                const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { x: B.x, y: B.y, width: B.width, height: B.height });
+                const inkDoc = Docs.Create.InkDocument(InkingControl.Instance.selectedColor, InkingControl.Instance.selectedTool, parseInt(InkingControl.Instance.selectedWidth), points, { x: B.x, y: B.y, _width: B.width, _height: B.height });
                 this.addDocument(inkDoc);
                 e.stopPropagation();
                 break;
@@ -375,7 +373,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     }
                     return pass;
                 });
-                this.addDocument(Docs.Create.FreeformDocument(sel, { x: bounds.x, y: bounds.y, width: bWidth, height: bHeight, panX: 0, panY: 0 }));
+                this.addDocument(Docs.Create.FreeformDocument(sel, { x: bounds.x, y: bounds.y, _width: bWidth, _height: bHeight, _panX: 0, _panY: 0 }));
                 sel.forEach(d => this.props.removeDocument(d));
                 break;
 
@@ -397,11 +395,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // I think it makes sense for the marquee menu to go away when panned. -syip2
         MarqueeOptionsMenu.Instance.fadeOut(true);
 
-        let x = this.Document.panX || 0;
-        let y = this.Document.panY || 0;
+        let x = this.Document._panX || 0;
+        let y = this.Document._panY || 0;
         const docs = this.childLayoutPairs.map(pair => pair.layout);
         const [dx, dy] = this.getTransform().transformDirection(e.clientX - this._lastX, e.clientY - this._lastY);
-        if (!this.isAnnotationOverlay) {
+        if (!this.isAnnotationOverlay && docs.length) {
             PDFMenu.Instance.fadeOut(true);
             const minx = this.childDataProvider(docs[0]).x;//docs.length ? NumCast(docs[0].x) : 0;
             const miny = this.childDataProvider(docs[0]).y;//docs.length ? NumCast(docs[0].y) : 0;
@@ -591,8 +589,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             const scale = this.getLocalTransform().inverse().Scale;
             const newPanX = Math.min((1 - 1 / scale) * this.nativeWidth, Math.max(0, panX));
             const newPanY = Math.min((this.props.Document.scrollHeight !== undefined ? NumCast(this.Document.scrollHeight) : (1 - 1 / scale) * this.nativeHeight), Math.max(0, panY));
-            this.Document.panX = this.isAnnotationOverlay ? newPanX : panX;
-            this.Document.panY = this.isAnnotationOverlay ? newPanY : panY;
+            this.Document._panX = this.isAnnotationOverlay ? newPanX : panX;
+            this.Document._panY = this.isAnnotationOverlay ? newPanY : panY;
         }
     }
 
@@ -616,14 +614,14 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
         // TODO This technically isn't correct if type !== "doc", as 
         // currently nothing is done, but we should probably push a new state
-        if (state.type === "doc" && this.Document.panX !== undefined && this.Document.panY !== undefined) {
+        if (state.type === "doc" && this.Document._panX !== undefined && this.Document._panY !== undefined) {
             const init = state.initializers![this.Document[Id]];
             if (!init) {
-                state.initializers![this.Document[Id]] = { panX: this.Document.panX, panY: this.Document.panY };
+                state.initializers![this.Document[Id]] = { panX: this.Document._panX, panY: this.Document._panY };
                 HistoryUtil.pushState(state);
             } else if (init.panX !== this.Document.panX || init.panY !== this.Document.panY) {
-                init.panX = this.Document.panX;
-                init.panY = this.Document.panY;
+                init.panX = this.Document._panX;
+                init.panY = this.Document._panY;
                 HistoryUtil.pushState(state);
             }
         }
@@ -639,13 +637,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             }
         } else {
             const layoutdoc = Doc.Layout(doc);
-            const newPanX = NumCast(doc.x) + NumCast(layoutdoc.width) / 2;
-            const newPanY = NumCast(doc.y) + NumCast(layoutdoc.height) / 2;
+            const newPanX = NumCast(doc.x) + NumCast(layoutdoc._width) / 2;
+            const newPanY = NumCast(doc.y) + NumCast(layoutdoc._height) / 2;
             const newState = HistoryUtil.getState();
             newState.initializers![this.Document[Id]] = { panX: newPanX, panY: newPanY };
             HistoryUtil.pushState(newState);
 
-            const savedState = { px: this.Document.panX, py: this.Document.panY, s: this.Document.scale, pt: this.Document.panTransformType };
+            const savedState = { px: this.Document._panX, py: this.Document._panY, s: this.Document.scale, pt: this.Document.panTransformType };
 
             if (!doc.z) this.setPan(newPanX, newPanY, "Ease"); // docs that are floating in their collection can't be panned to from their collection -- need to propagate the pan to a parent freeform somehow
             Doc.BrushDoc(this.props.Document);
@@ -655,8 +653,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
             afterFocus && setTimeout(() => {
                 if (afterFocus && afterFocus()) {
-                    this.Document.panX = savedState.px;
-                    this.Document.panY = savedState.py;
+                    this.Document._panX = savedState.px;
+                    this.Document._panY = savedState.py;
                     this.Document.scale = savedState.s;
                     this.Document.panTransformType = savedState.pt;
                 }
@@ -666,7 +664,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     }
 
     setScaleToZoom = (doc: Doc, scale: number = 0.5) => {
-        this.Document.scale = scale * Math.min(this.props.PanelWidth() / NumCast(doc.width), this.props.PanelHeight() / NumCast(doc.height));
+        this.Document.scale = scale * Math.min(this.props.PanelWidth() / NumCast(doc._width), this.props.PanelHeight() / NumCast(doc._height));
     }
 
     zoomToScale = (scale: number) => {
@@ -709,7 +707,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             return { ...result, transition: "transform 1s" };
         }
         const layoutDoc = Doc.Layout(params.doc);
-        return { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(layoutDoc.width, "number"), height: Cast(layoutDoc.height, "number") };
+        return { x: Cast(params.doc.x, "number"), y: Cast(params.doc.y, "number"), z: Cast(params.doc.z, "number"), width: Cast(layoutDoc._width, "number"), height: Cast(layoutDoc._height, "number") };
     }
 
     viewDefsToJSX = (views: any[]) => {
@@ -735,7 +733,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         }
     }
 
-    childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc) { return this._layoutPoolData.get(doc[Id]); }.bind(this));
+    childDataProvider = computedFn(function childDataProvider(this: any, doc: Doc) {
+        if (!doc) {
+            console.log(doc);
+        }
+        return this._layoutPoolData.get(doc[Id]);
+    }.bind(this));
 
     doPivotLayout(poolData: ObservableMap<string, any>) {
         return computePivotLayout(poolData, this.props.Document, this.childDocs,
@@ -761,7 +764,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     get doLayoutComputation() {
         let computedElementData: { elements: ViewDefResult[] };
-        switch (this.Document.freeformLayoutEngine) {
+        switch (this.Document._freeformLayoutEngine) {
             case "pivot": computedElementData = this.doPivotLayout(this._layoutPoolData); break;
             default: computedElementData = this.doFreeformLayout(this._layoutPoolData); break;
         }
@@ -770,7 +773,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 ele: <CollectionFreeFormDocumentView key={pair.layout[Id]}  {...this.getChildDocumentViewProps(pair.layout, pair.data)}
                     dataProvider={this.childDataProvider}
                     jitterRotation={NumCast(this.props.Document.jitterRotation)}
-                    fitToBox={this.props.fitToBox || this.Document.freeformLayoutEngine === "pivot"} />,
+                    fitToBox={this.props.fitToBox || this.Document._freeformLayoutEngine === "pivot"} />,
                 bounds: this.childDataProvider(pair.layout)
             }));
 
@@ -797,12 +800,12 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     layoutDocsInGrid = () => {
         UndoManager.RunInBatch(() => {
             const docs = DocListCast(this.Document[this.props.fieldKey]);
-            const startX = this.Document.panX || 0;
+            const startX = this.Document._panX || 0;
             let x = startX;
-            let y = this.Document.panY || 0;
+            let y = this.Document._panY || 0;
             let i = 0;
-            const width = Math.max(...docs.map(doc => NumCast(doc.width)));
-            const height = Math.max(...docs.map(doc => NumCast(doc.height)));
+            const width = Math.max(...docs.map(doc => NumCast(doc._width)));
+            const height = Math.max(...docs.map(doc => NumCast(doc._height)));
             for (const doc of docs) {
                 doc.x = x;
                 doc.y = y;
@@ -880,8 +883,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         const layoutItems: ContextMenuProps[] = [];
 
         layoutItems.push({ description: "reset view", event: () => { this.props.Document.panX = this.props.Document.panY = 0; this.props.Document.scale = 1; }, icon: "compress-arrows-alt" });
-        layoutItems.push({ description: `${this.Document.LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document.LODdisable = !this.Document.LODdisable, icon: "table" });
-        layoutItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document.fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
+        layoutItems.push({ description: `${this.Document._LODdisable ? "Enable LOD" : "Disable LOD"}`, event: () => this.Document._LODdisable = !this.Document._LODdisable, icon: "table" });
+        layoutItems.push({ description: `${this.fitToContent ? "Unset" : "Set"} Fit To Container`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
         layoutItems.push({ description: `${this.Document.useClusters ? "Uncluster" : "Use Clusters"}`, event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
         layoutItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
         layoutItems.push({ description: "Analyze Strokes", event: this.analyzeStrokes, icon: "paint-brush" });
@@ -918,7 +921,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
             description: "Add Note ...",
             subitems: DocListCast((CurrentUserUtils.UserDocument.noteTypes as Doc).data).map((note, i) => ({
                 description: (i + 1) + ": " + StrCast(note.title),
-                event: (args: { x: number, y: number }) => this.addLiveTextBox(Docs.Create.TextDocument({ width: 200, height: 100, x: this.getTransform().transformPoint(args.x, args.y)[0], y: this.getTransform().transformPoint(args.x, args.y)[1], autoHeight: true, layout: note, title: StrCast(note.title) })),
+                event: (args: { x: number, y: number }) => this.addLiveTextBox(Docs.Create.TextDocument({ _width: 200, _height: 100, x: this.getTransform().transformPoint(args.x, args.y)[0], y: this.getTransform().transformPoint(args.x, args.y)[1], autoHeight: true, layout: note, title: StrCast(note.title) })),
                 icon: "eye"
             })) as ContextMenuProps[],
             icon: "eye"
@@ -939,7 +942,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
 
     children = () => {
         const eles: JSX.Element[] = [];
-        this.extensionDoc && (eles.push(...this.childViews()));
+        eles.push(...this.childViews());
         // this._palette && (eles.push(this._palette));
         // this.currentStroke && (eles.push(this.currentStroke));
         eles.push(<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />);
@@ -951,7 +954,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         </div>;
     }
     @computed get marqueeView() {
-        return <MarqueeView {...this.props} extensionDoc={this.extensionDoc!} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
+        return <MarqueeView {...this.props} activeDocuments={this.getActiveDocuments} selectDocuments={this.selectDocuments} addDocument={this.addDocument}
             addLiveTextDocument={this.addLiveTextBox} getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
             <CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
                 easing={this.easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
@@ -973,7 +976,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
         // this.Document.fitH = this.contentBounds && (this.contentBounds.b - this.contentBounds.y);
         // if isAnnotationOverlay is set, then children will be stored in the extension document for the fieldKey.
         // otherwise, they are stored in fieldKey.  All annotations to this document are stored in the extension document
-        if (!this.extensionDoc) return (null);
         // let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
         return <div className={"collectionfreeformview-container"}
             ref={this.createDashEventsTarget}
@@ -986,7 +988,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                 width: this.contentScaling ? `${100 / this.contentScaling}%` : "",
                 height: this.contentScaling ? `${100 / this.contentScaling}%` : this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
             }}>
-            {!this.Document.LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
+            {!this.Document._LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
                 this.placeholder : this.marqueeView}
             <CollectionFreeFormOverlayView elements={this.elementFunc} />
         </div>;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 584d18372..0e02d1ef2 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -29,7 +29,6 @@ interface MarqueeViewProps {
     removeDocument: (doc: Doc) => boolean;
     addLiveTextDocument: (doc: Doc) => void;
     isSelected: () => boolean;
-    extensionDoc: Doc;
     isAnnotationOverlay?: boolean;
     setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
 }
@@ -85,7 +84,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 }
                 ns.map(line => {
                     const indent = line.search(/\S|$/);
-                    const newBox = Docs.Create.TextDocument({ width: 200, height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line });
+                    const newBox = Docs.Create.TextDocument({ _width: 200, _height: 35, x: x + indent / 3 * 10, y: y, documentText: "@@@" + line, title: line });
                     this.props.addDocument(newBox);
                     y += 40 * this.props.getTransform().Scale;
                 });
@@ -95,17 +94,17 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             navigator.clipboard.readText().then(text => {
                 const ns = text.split("\n").filter(t => t.trim() !== "\r" && t.trim() !== "");
                 if (ns.length === 1 && text.startsWith("http")) {
-                    this.props.addDocument(Docs.Create.ImageDocument(text, { nativeWidth: 300, width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
+                    this.props.addDocument(Docs.Create.ImageDocument(text, { _nativeWidth: 300, _width: 300, x: x, y: y }));// paste an image from its URL in the paste buffer
                 } else {
                     this.pasteTable(ns, x, y);
                 }
             });
         } else if (!e.ctrlKey) {
             this.props.addLiveTextDocument(
-                Docs.Create.TextDocument({ width: 200, height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" }));
+                Docs.Create.TextDocument({ _width: 200, _height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" }));
         } else if (e.keyCode > 48 && e.keyCode <= 57) {
             const notes = DocListCast((CurrentUserUtils.UserDocument.noteTypes as Doc).data);
-            const text = Docs.Create.TextDocument({ width: 200, height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" });
+            const text = Docs.Create.TextDocument({ _width: 200, _height: 100, x: x, y: y, autoHeight: true, title: "-typed text-" });
             text.layout = notes[(e.keyCode - 49) % notes.length];
             this.props.addLiveTextDocument(text);
         }
@@ -128,7 +127,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             let groupAttr: string | number = "";
             const rowProto = new Doc();
             rowProto.title = rowProto.Id;
-            rowProto.width = 200;
+            rowProto._width = 200;
             rowProto.isPrototype = true;
             for (let i = 1; i < ns.length - 1; i++) {
                 const values = ns[i].split("\t");
@@ -144,10 +143,10 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 }
                 docDataProto.title = i.toString();
                 const doc = Doc.MakeDelegate(docDataProto);
-                doc.width = 200;
+                doc._width = 200;
                 docList.push(doc);
             }
-            const newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
+            const newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", _width: 300, _height: 100 });
 
             this.props.addDocument(newCol);
         }
@@ -267,15 +266,15 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
     }
 
     get inkDoc() {
-        return this.props.extensionDoc;
+        return this.props.Document;
     }
 
     get ink() { // ink will be stored on the extension doc for the field (fieldKey) where the container's data is stored.
-        return this.props.extensionDoc && Cast(this.props.extensionDoc.ink, InkField);
+        return Cast(this.props.Document.ink, InkField);
     }
 
     set ink(value: InkField | undefined) {
-        this.props.extensionDoc && (this.props.extensionDoc.ink = value);
+        this.props.Document.ink = value;
     }
 
     @action
@@ -325,13 +324,13 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         const newCollection = Docs.Create.FreeformDocument(selected, {
             x: bounds.left,
             y: bounds.top,
-            panX: 0,
-            panY: 0,
+            _panX: 0,
+            _panY: 0,
             backgroundColor: this.props.isAnnotationOverlay ? undefined : chosenColor,
             defaultBackgroundColor: this.props.isAnnotationOverlay ? undefined : chosenColor,
-            width: bounds.width,
-            height: bounds.height,
-            LODdisable: true,
+            _width: bounds.width,
+            _height: bounds.height,
+            _LODdisable: true,
             title: "a nested collection",
         });
         // const dataExtensionField = Doc.CreateDocumentExtensionForField(newCollection, "data");
@@ -374,16 +373,17 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             d.page = -1;
             return d;
         });
-        newCollection.chromeStatus = "disabled";
-        const summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, width: 300, height: 100, autoHeight: true, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
+        newCollection._chromeStatus = "disabled";
+        const summary = Docs.Create.TextDocument({ x: bounds.left, y: bounds.top, _width: 300, _height: 100, autoHeight: true, backgroundColor: "#e2ad32" /* yellow */, title: "-summary-" });
         Doc.GetProto(summary).summarizedDocs = new List<Doc>([newCollection]);
         newCollection.x = bounds.left + bounds.width;
         Doc.GetProto(newCollection).summaryDoc = summary;
         Doc.GetProto(newCollection).title = ComputedField.MakeFunction(`summaryTitle(this);`);
         if (e instanceof KeyboardEvent ? e.key === "s" : true) { // summary is wrapped in an expand/collapse container that also contains the summarized documents in a free form view.
-            const container = Docs.Create.FreeformDocument([summary, newCollection], { x: bounds.left, y: bounds.top, width: 300, height: 200, chromeStatus: "disabled", title: "-summary-" });
-            container.viewType = CollectionViewType.Stacking;
-            container.autoHeight = true;
+            const container = Docs.Create.FreeformDocument([summary, newCollection], {
+                x: bounds.left, y: bounds.top, _width: 300, _height: 200, autoHeight: true,
+                _viewType: CollectionViewType.Stacking, _chromeStatus: "disabled", title: "-summary-"
+            });
             Doc.GetProto(summary).maximizeLocation = "inPlace";  // or "onRight"
             this.props.addLiveTextDocument(container);
         } else if (e instanceof KeyboardEvent ? e.key === "S" : false) { // the summary stands alone, but is linked to a collection of the summarized documents - set the OnCLick behavior to link follow to access them
@@ -468,8 +468,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
             const layoutDoc = Doc.Layout(doc);
             const x = NumCast(doc.x);
             const y = NumCast(doc.y);
-            const w = NumCast(layoutDoc.width);
-            const h = NumCast(layoutDoc.height);
+            const w = NumCast(layoutDoc._width);
+            const h = NumCast(layoutDoc._height);
             if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
                 selection.push(doc);
             }
@@ -479,8 +479,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 const layoutDoc = Doc.Layout(doc);
                 const x = NumCast(doc.x);
                 const y = NumCast(doc.y);
-                const w = NumCast(layoutDoc.width);
-                const h = NumCast(layoutDoc.height);
+                const w = NumCast(layoutDoc._width);
+                const h = NumCast(layoutDoc._height);
                 if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
                     selection.push(doc);
                 }
@@ -496,8 +496,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 const layoutDoc = Doc.Layout(doc);
                 const x = NumCast(doc.x);
                 const y = NumCast(doc.y);
-                const w = NumCast(layoutDoc.width);
-                const h = NumCast(layoutDoc.height);
+                const w = NumCast(layoutDoc._width);
+                const h = NumCast(layoutDoc._height);
                 if (this.intersectRect({ left: x, top: y, width: w, height: h }, otherBounds)) {
                     selection.push(doc);
                 }
diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx
index bb8a8b47b..e3bf6b5f8 100644
--- a/src/client/views/linking/LinkEditor.tsx
+++ b/src/client/views/linking/LinkEditor.tsx
@@ -292,7 +292,7 @@ export class LinkGroupEditor extends React.Component<LinkGroupEditorProps> {
         if (index > -1) keys.splice(index, 1);
         const cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
         const docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
-        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
+        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { _width: 500, _height: 300, title: groupType + " table" }));
         const ref = React.createRef<HTMLDivElement>();
         return <div ref={ref}><button className="linkEditor-button" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>;
     }
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index 29e167ff7..325c92413 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -89,7 +89,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     async resetPan() {
         if (LinkFollowBox.destinationDoc && this.sourceView && this.sourceView.props.ContainingCollectionDoc) {
             runInAction(() => this.canPan = false);
-            if (this.sourceView.props.ContainingCollectionDoc.viewType === CollectionViewType.Freeform) {
+            if (this.sourceView.props.ContainingCollectionDoc._viewType === CollectionViewType.Freeform) {
                 const docs = Cast(this.sourceView.props.ContainingCollectionDoc.data, listSpec(Doc), []);
                 const aliases = await SearchUtil.GetViewsOfDocument(Doc.GetProto(LinkFollowBox.destinationDoc));
 
@@ -165,11 +165,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     @undoBatch
     openColFullScreen = (options: { context: Doc }) => {
         if (LinkFollowBox.destinationDoc) {
-            if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
-                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2;
-                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2;
-                options.context.panX = newPanX;
-                options.context.panY = newPanY;
+            if (NumCast(options.context._viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
+                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc._width) / 2;
+                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc._height) / 2;
+                options.context._panX = newPanX;
+                options.context._panY = newPanY;
             }
             const view = DocumentManager.Instance.getDocumentView(options.context);
             view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
@@ -193,11 +193,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     openLinkColRight = (options: { context: Doc, shouldZoom: boolean }) => {
         if (LinkFollowBox.destinationDoc) {
             options.context = Doc.IsPrototype(options.context) ? Doc.MakeDelegate(options.context) : options.context;
-            if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
-                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2;
-                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2;
-                options.context.panX = newPanX;
-                options.context.panY = newPanY;
+            if (NumCast(options.context._viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
+                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc._width) / 2;
+                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc._height) / 2;
+                options.context._panX = newPanX;
+                options.context._panY = newPanY;
             }
             (LinkFollowBox._addDocTab || this.props.addDocTab)(options.context, undefined, "onRight");
 
@@ -245,11 +245,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     openLinkColTab = (options: { context: Doc, shouldZoom: boolean }) => {
         if (LinkFollowBox.destinationDoc) {
             options.context = Doc.IsPrototype(options.context) ? Doc.MakeDelegate(options.context) : options.context;
-            if (NumCast(options.context.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
-                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc.width) / 2;
-                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc.height) / 2;
-                options.context.panX = newPanX;
-                options.context.panY = newPanY;
+            if (NumCast(options.context._viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
+                const newPanX = NumCast(LinkFollowBox.destinationDoc.x) + NumCast(LinkFollowBox.destinationDoc._width) / 2;
+                const newPanY = NumCast(LinkFollowBox.destinationDoc.y) + NumCast(LinkFollowBox.destinationDoc._height) / 2;
+                options.context._panX = newPanX;
+                options.context._panY = newPanY;
             }
             (LinkFollowBox._addDocTab || this.props.addDocTab)(options.context, undefined, "inTab");
             if (options.shouldZoom) this.jumpToLink({ shouldZoom: options.shouldZoom });
@@ -270,13 +270,13 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
                     const y = NumCast(LinkFollowBox.sourceDoc.y);
                     const x = NumCast(LinkFollowBox.sourceDoc.x);
 
-                    const width = NumCast(LinkFollowBox.sourceDoc.width);
-                    const height = NumCast(LinkFollowBox.sourceDoc.height);
+                    const width = NumCast(LinkFollowBox.sourceDoc._width);
+                    const height = NumCast(LinkFollowBox.sourceDoc._height);
 
                     alias.x = x + width + 30;
                     alias.y = y;
-                    alias.width = width;
-                    alias.height = height;
+                    alias._width = width;
+                    alias._height = height;
 
                     this.sourceView.props.addDocument(alias);
                 }
@@ -361,7 +361,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
     get canOpenInPlace() {
         if (this.sourceView && this.sourceView.props.ContainingCollectionDoc) {
             const colDoc = this.sourceView.props.ContainingCollectionDoc;
-            if (colDoc.viewType && colDoc.viewType === CollectionViewType.Freeform) return true;
+            if (colDoc._viewType === CollectionViewType.Freeform) return true;
         }
         return false;
     }
@@ -481,7 +481,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
         let contextMatch: boolean = false;
         if (this.selectedContextAliases) {
             this.selectedContextAliases.forEach(alias => {
-                if (alias.viewType === CollectionViewType.Freeform) contextMatch = true;
+                if (alias._viewType === CollectionViewType.Freeform) contextMatch = true;
             });
         }
         if (contextMatch) return true;
@@ -523,7 +523,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
 
     render() {
         return (
-            <div className="linkFollowBox-main" style={{ height: NumCast(this.props.Document.height), width: NumCast(this.props.Document.width) }}>
+            <div className="linkFollowBox-main" style={{ height: NumCast(this.props.Document._height), width: NumCast(this.props.Document._width) }}>
                 <div className="linkFollowBox-header">
                     <div className="topHeader">
                         {LinkFollowBox.linkDoc ? "Link Title: " + StrCast(LinkFollowBox.linkDoc.title) : "No Link Selected"}
@@ -533,7 +533,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
                         LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc ? "Source: " + StrCast(LinkFollowBox.sourceDoc.title) + ", Destination: " + StrCast(LinkFollowBox.destinationDoc.title)
                             : "" : ""}</div>
                 </div>
-                <div className="linkFollowBox-content" style={{ height: NumCast(this.props.Document.height) - 110 }}>
+                <div className="linkFollowBox-content" style={{ height: NumCast(this.props.Document._height) - 110 }}>
                     <div className="linkFollowBox-item">
                         <div className="linkFollowBox-item title">Mode</div>
                         <div className="linkFollowBox-itemContent">
diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx
index ace9a9e4c..0c38ff45c 100644
--- a/src/client/views/linking/LinkMenuGroup.tsx
+++ b/src/client/views/linking/LinkMenuGroup.tsx
@@ -58,7 +58,7 @@ export class LinkMenuGroup extends React.Component<LinkMenuGroupProps> {
         if (index > -1) keys.splice(index, 1);
         const cols = ["anchor1", "anchor2", ...[...keys]].map(c => new SchemaHeaderField(c, "#f1efeb"));
         const docs: Doc[] = LinkManager.Instance.getAllMetadataDocsInGroup(groupType);
-        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { width: 500, height: 300, title: groupType + " table" }));
+        const createTable = action(() => Docs.Create.SchemaDocument(cols, docs, { _width: 500, _height: 300, title: groupType + " table" }));
         const ref = React.createRef<HTMLDivElement>();
         return <div ref={ref}><button className="linkEditor-button linkEditor-tableButton" onPointerDown={SetupDrag(ref, createTable)} title="Drag to view relationship table"><FontAwesomeIcon icon="table" size="sm" /></button></div>;
     }
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 95c765e8a..8ede79edc 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -68,7 +68,7 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
                 this.Document.playOnSelect && sel && !Doc.AreProtosEqual(sel, this.props.Document) && this.playFrom(DateCast(sel.creationTime).date.getTime());
             });
         this._scrubbingDisposer = reaction(() => AudioBox._scrubTime, timeInMillisecondsFrom1970 => {
-            const start = this.extensionDoc && DateCast(this.extensionDoc.recordingStart);
+            const start = DateCast(this.dataDoc[this.props.fieldKey + "-recordingStart"]);
             start && this.playFrom((timeInMillisecondsFrom1970 - start.date.getTime()) / 1000);
         });
     }
@@ -128,13 +128,12 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
     recordAudioAnnotation = () => {
         let gumStream: any;
         const self = this;
-        const extensionDoc = this.extensionDoc;
-        extensionDoc && navigator.mediaDevices.getUserMedia({
+        navigator.mediaDevices.getUserMedia({
             audio: true
         }).then(function (stream) {
             gumStream = stream;
             self._recorder = new MediaRecorder(stream);
-            extensionDoc.recordingStart = new DateField(new Date());
+            self.dataDoc[self.props.fieldKey + "-recordingStart"] = new DateField(new Date());
             AudioBox.ActiveRecordings.push(self.props.Document);
             self._recorder.ondataavailable = async function (e: any) {
                 const formData = new FormData();
@@ -213,55 +212,53 @@ export class AudioBox extends DocExtendableComponent<FieldViewProps, AudioDocume
 
     render() {
         const interactive = this.active() ? "-interactive" : "";
-        return (!this.extensionDoc ? (null) :
-            <div className={`audiobox-container`} onContextMenu={this.specificContextMenu}
-                onClick={!this.path ? this.recordClick : undefined}>
-                <div className="audiobox-handle"></div>
-                {!this.path ?
-                    <button className={`audiobox-record${interactive}`} style={{ backgroundColor: this._audioState === "recording" ? "red" : "black" }}>
-                        {this._audioState === "recording" ? "STOP" : "RECORD"}
-                    </button> :
-                    <div className="audiobox-controls">
-                        <div className="audiobox-player" onClick={this.onPlay}>
-                            <div className="audiobox-playhead"> <FontAwesomeIcon style={{ width: "100%" }} icon={this._playing ? "pause" : "play"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
-                            <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%" }} icon="stop" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
-                            <div className="audiobox-timeline" onClick={e => e.stopPropagation()}
-                                onPointerDown={e => {
-                                    if (e.button === 0 && !e.ctrlKey) {
-                                        const rect = (e.target as any).getBoundingClientRect();
-                                        this._ele!.currentTime = this.Document.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
-                                        this.pause();
-                                        e.stopPropagation();
-                                    }
-                                }} >
-                                {DocListCast(this.dataDoc.links).map((l, i) => {
-                                    let la1 = l.anchor1 as Doc;
-                                    let la2 = l.anchor2 as Doc;
-                                    let linkTime = NumCast(l.anchor2Timecode);
-                                    if (Doc.AreProtosEqual(la1, this.dataDoc)) {
-                                        la1 = l.anchor2 as Doc;
-                                        la2 = l.anchor1 as Doc;
-                                        linkTime = NumCast(l.anchor1Timecode);
-                                    }
-                                    return !linkTime ? (null) :
-                                        <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
-                                            <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
-                                                <DocumentView {...this.props} Document={l} layoutKey={Doc.LinkEndpoint(l, la2)}
-                                                    parentActive={returnTrue} bringToFront={emptyFunction} zoomToScale={emptyFunction} getScale={returnOne}
-                                                    backgroundColor={returnTransparent} />
-                                            </div>
-                                            <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
-                                                onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); } }}
-                                                onClick={e => { if (e.button === 0 && !e.ctrlKey) { this.pause(); e.stopPropagation(); } }} />
-                                        </div>;
-                                })}
-                                <div className="audiobox-current" style={{ left: `${NumCast(this.Document.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
-                                {this.audio}
-                            </div>
+        return <div className={`audiobox-container`} onContextMenu={this.specificContextMenu}
+            onClick={!this.path ? this.recordClick : undefined}>
+            <div className="audiobox-handle"></div>
+            {!this.path ?
+                <button className={`audiobox-record${interactive}`} style={{ backgroundColor: this._audioState === "recording" ? "red" : "black" }}>
+                    {this._audioState === "recording" ? "STOP" : "RECORD"}
+                </button> :
+                <div className="audiobox-controls">
+                    <div className="audiobox-player" onClick={this.onPlay}>
+                        <div className="audiobox-playhead"> <FontAwesomeIcon style={{ width: "100%" }} icon={this._playing ? "pause" : "play"} size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
+                        <div className="audiobox-playhead" onClick={this.onStop}><FontAwesomeIcon style={{ width: "100%" }} icon="stop" size={this.props.PanelHeight() < 36 ? "1x" : "2x"} /></div>
+                        <div className="audiobox-timeline" onClick={e => e.stopPropagation()}
+                            onPointerDown={e => {
+                                if (e.button === 0 && !e.ctrlKey) {
+                                    const rect = (e.target as any).getBoundingClientRect();
+                                    this._ele!.currentTime = this.Document.currentTimecode = (e.clientX - rect.x) / rect.width * NumCast(this.dataDoc.duration);
+                                    this.pause();
+                                    e.stopPropagation();
+                                }
+                            }} >
+                            {DocListCast(this.dataDoc.links).map((l, i) => {
+                                let la1 = l.anchor1 as Doc;
+                                let la2 = l.anchor2 as Doc;
+                                let linkTime = NumCast(l.anchor2Timecode);
+                                if (Doc.AreProtosEqual(la1, this.dataDoc)) {
+                                    la1 = l.anchor2 as Doc;
+                                    la2 = l.anchor1 as Doc;
+                                    linkTime = NumCast(l.anchor1Timecode);
+                                }
+                                return !linkTime ? (null) :
+                                    <div className={this.props.PanelHeight() < 32 ? "audiobox-marker-minicontainer" : "audiobox-marker-container"} key={l[Id]} style={{ left: `${linkTime / NumCast(this.dataDoc.duration, 1) * 100}%` }}>
+                                        <div className={this.props.PanelHeight() < 32 ? "audioBox-linker-mini" : "audioBox-linker"} key={"linker" + i}>
+                                            <DocumentView {...this.props} Document={l} layoutKey={Doc.LinkEndpoint(l, la2)}
+                                                parentActive={returnTrue} bringToFront={emptyFunction} zoomToScale={emptyFunction} getScale={returnOne}
+                                                backgroundColor={returnTransparent} />
+                                        </div>
+                                        <div key={i} className="audiobox-marker" onPointerEnter={() => Doc.linkFollowHighlight(la1)}
+                                            onPointerDown={e => { if (e.button === 0 && !e.ctrlKey) { this.playFrom(linkTime); e.stopPropagation(); } }}
+                                            onClick={e => { if (e.button === 0 && !e.ctrlKey) { this.pause(); e.stopPropagation(); } }} />
+                                    </div>;
+                            })}
+                            <div className="audiobox-current" style={{ left: `${NumCast(this.Document.currentTimecode) / NumCast(this.dataDoc.duration, 1) * 100}%` }} />
+                            {this.audio}
                         </div>
                     </div>
-                }
-            </div>
-        );
+                </div>
+            }
+        </div>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index cd78f5d49..ea3c505d8 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -38,18 +38,18 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
         return (hgt === undefined && this.nativeWidth && this.nativeHeight) ? this.width * this.nativeHeight / this.nativeWidth : hgt;
     }
     @computed get dataProvider() { return this.props.dataProvider && this.props.dataProvider(this.props.Document) ? this.props.dataProvider(this.props.Document) : undefined; }
-    @computed get nativeWidth() { return NumCast(this.layoutDoc.nativeWidth); }
-    @computed get nativeHeight() { return NumCast(this.layoutDoc.nativeHeight); }
+    @computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth); }
+    @computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight); }
 
     @computed get renderScriptDim() {
         if (this.Document.renderScript) {
             const someView = Cast(this.props.Document.someView, Doc);
             const minimap = Cast(this.props.Document.minimap, Doc);
             if (someView instanceof Doc && minimap instanceof Doc) {
-                const x = (NumCast(someView.panX) - NumCast(someView.width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap.width) - NumCast(minimap.width) / 2;
-                const y = (NumCast(someView.panY) - NumCast(someView.height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap.height) - NumCast(minimap.height) / 2;
-                const w = NumCast(someView.width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width);
-                const h = NumCast(someView.height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height);
+                const x = (NumCast(someView._panX) - NumCast(someView._width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap._width) - NumCast(minimap._width) / 2;
+                const y = (NumCast(someView._panY) - NumCast(someView._height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap._height) - NumCast(minimap._height) / 2;
+                const w = NumCast(someView._width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width);
+                const h = NumCast(someView._height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height);
                 return { x: x, y: y, width: w, height: h };
             }
         }
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 96102e0e8..4f1bbd33c 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -44,8 +44,8 @@ interface ContentFittingDocumentViewProps {
 export class ContentFittingDocumentView extends React.Component<ContentFittingDocumentViewProps>{
     public get displayName() { return "DocumentView(" + this.props.Document?.title + ")"; } // this makes mobx trace() statements more descriptive
     private get layoutDoc() { return this.props.Document && Doc.Layout(this.props.Document); }
-    private get nativeWidth() { return NumCast(this.layoutDoc?.nativeWidth, this.props.PanelWidth()); }
-    private get nativeHeight() { return NumCast(this.layoutDoc?.nativeHeight, this.props.PanelHeight()); }
+    private get nativeWidth() { return NumCast(this.layoutDoc?._nativeWidth, this.props.PanelWidth()); }
+    private get nativeHeight() { return NumCast(this.layoutDoc?._nativeHeight, this.props.PanelHeight()); }
     private contentScaling = () => {
         const wscale = this.props.PanelWidth() / (this.nativeWidth || this.props.PanelWidth() || 1);
         if (wscale * this.nativeHeight > this.props.PanelHeight()) {
@@ -68,10 +68,10 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
         }
         return true;
     }
-    private PanelWidth = () => this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth();
-    private PanelHeight = () => this.nativeHeight && (!this.props.Document || !this.props.Document.fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight();
+    private PanelWidth = () => this.nativeWidth && (!this.props.Document || !this.props.Document._fitWidth) ? this.nativeWidth * this.contentScaling() : this.props.PanelWidth();
+    private PanelHeight = () => this.nativeHeight && (!this.props.Document || !this.props.Document._fitWidth) ? this.nativeHeight * this.contentScaling() : this.props.PanelHeight();
     private getTransform = () => this.props.getTransform().translate(-this.centeringOffset, -this.centeringYOffset).scale(1 / this.contentScaling());
-    private get centeringOffset() { return this.nativeWidth && (!this.props.Document || !this.props.Document.fitWidth) ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; }
+    private get centeringOffset() { return this.nativeWidth && (!this.props.Document || !this.props.Document._fitWidth) ? (this.props.PanelWidth() - this.nativeWidth * this.contentScaling()) / 2 : 0; }
     private get centeringYOffset() { return Math.abs(this.centeringOffset) < 0.001 ? (this.props.PanelHeight() - this.nativeHeight * this.contentScaling()) / 2 : 0; }
 
     @computed get borderRounding() { return StrCast(this.props.Document?.borderRounding); }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 2570d232a..5663e5e3c 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -108,8 +108,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     public get ContentDiv() { return this._mainCont.current; }
     @computed get active() { return SelectionManager.IsSelected(this, true) || this.props.parentActive(true); }
     @computed get topMost() { return this.props.renderDepth === 0; }
-    @computed get nativeWidth() { return this.layoutDoc.nativeWidth || 0; }
-    @computed get nativeHeight() { return this.layoutDoc.nativeHeight || 0; }
+    @computed get nativeWidth() { return this.layoutDoc._nativeWidth || 0; }
+    @computed get nativeHeight() { return this.layoutDoc._nativeHeight || 0; }
     @computed get onClickHandler() { return this.props.onClick ? this.props.onClick : this.Document.onClick; }
     @computed get onPointerDownHandler() { return this.props.onPointerDown ? this.props.onPointerDown : this.Document.onPointerDown; }
     @computed get onPointerUpHandler() { return this.props.onPointerUp ? this.props.onPointerUp : this.Document.onPointerUp; }
@@ -343,7 +343,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             if (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3) {
                 if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick)) {
                     this.cleanUpInteractions();
-                    this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
+                    this.startDragging(this._downX, this._downY, this.Document._dropAction ? this.Document._dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
                 }
             }
             e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document'  however it does mark the event as cancelBubble=true which we test for in the move event handlers
@@ -387,10 +387,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             if (dX !== 0 || dY !== 0 || dW !== 0 || dH !== 0) {
                 const doc = PositionDocument(this.props.Document);
                 const layoutDoc = PositionDocument(Doc.Layout(this.props.Document));
-                let nwidth = layoutDoc.nativeWidth || 0;
-                let nheight = layoutDoc.nativeHeight || 0;
-                const width = (layoutDoc.width || 0);
-                const height = (layoutDoc.height || (nheight / nwidth * width));
+                let nwidth = layoutDoc._nativeWidth || 0;
+                let nheight = layoutDoc._nativeHeight || 0;
+                const width = (layoutDoc._width || 0);
+                const height = (layoutDoc._height || (nheight / nwidth * width));
                 const scale = this.props.ScreenToLocalTransform().Scale * this.props.ContentScaling();
                 const actualdW = Math.max(width + (dW * scale), 20);
                 const actualdH = Math.max(height + (dH * scale), 20);
@@ -400,33 +400,33 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 if (fixedAspect && e.ctrlKey && layoutDoc.ignoreAspect) {
                     layoutDoc.ignoreAspect = false;
 
-                    layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0;
-                    layoutDoc.nativeHeight = nheight = layoutDoc.height || 0;
+                    layoutDoc._nativeWidth = nwidth = layoutDoc._width || 0;
+                    layoutDoc._nativeHeight = nheight = layoutDoc._height || 0;
                 }
                 if (fixedAspect && (!nwidth || !nheight)) {
-                    layoutDoc.nativeWidth = nwidth = layoutDoc.width || 0;
-                    layoutDoc.nativeHeight = nheight = layoutDoc.height || 0;
+                    layoutDoc._nativeWidth = nwidth = layoutDoc._width || 0;
+                    layoutDoc._nativeHeight = nheight = layoutDoc._height || 0;
                 }
                 if (nwidth > 0 && nheight > 0 && !layoutDoc.ignoreAspect) {
                     if (Math.abs(dW) > Math.abs(dH)) {
                         if (!fixedAspect) {
-                            layoutDoc.nativeWidth = actualdW / (layoutDoc.width || 1) * (layoutDoc.nativeWidth || 0);
+                            layoutDoc._nativeWidth = actualdW / (layoutDoc._width || 1) * (layoutDoc._nativeWidth || 0);
                         }
-                        layoutDoc.width = actualdW;
-                        if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.height = nheight / nwidth * layoutDoc.width;
-                        else layoutDoc.height = actualdH;
+                        layoutDoc._width = actualdW;
+                        if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._height = nheight / nwidth * layoutDoc._width;
+                        else layoutDoc._height = actualdH;
                     }
                     else {
                         if (!fixedAspect) {
-                            layoutDoc.nativeHeight = actualdH / (layoutDoc.height || 1) * (doc.nativeHeight || 0);
+                            layoutDoc._nativeHeight = actualdH / (layoutDoc._height || 1) * (doc._nativeHeight || 0);
                         }
-                        layoutDoc.height = actualdH;
-                        if (fixedAspect && !layoutDoc.fitWidth) layoutDoc.width = nwidth / nheight * layoutDoc.height;
-                        else layoutDoc.width = actualdW;
+                        layoutDoc._height = actualdH;
+                        if (fixedAspect && !layoutDoc._fitWidth) layoutDoc._width = nwidth / nheight * layoutDoc._height;
+                        else layoutDoc._width = actualdW;
                     }
                 } else {
-                    dW && (layoutDoc.width = actualdW);
-                    dH && (layoutDoc.height = actualdH);
+                    dW && (layoutDoc._width = actualdW);
+                    dH && (layoutDoc._height = actualdH);
                     dH && layoutDoc.autoHeight && (layoutDoc.autoHeight = false);
                 }
             }
@@ -484,7 +484,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 if (!e.altKey && (!this.topMost || this.Document.onDragStart || this.Document.onClick) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) {
                     document.removeEventListener("pointermove", this.onPointerMove);
                     document.removeEventListener("pointerup", this.onPointerUp);
-                    this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
+                    this.startDragging(this._downX, this._downY, this.Document._dropAction ? this.Document._dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined, this._hitTemplateDrag);
                 }
             }
             e.stopPropagation(); // doesn't actually stop propagation since all our listeners are listening to events on 'document'  however it does mark the event as cancelBubble=true which we test for in the move event handlers
@@ -520,12 +520,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         undoBatch(() => doc.layoutKey = "layout")();
     }
 
-    static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>) => {
+    static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, name: string = "custom") => {
         const batch = UndoManager.StartBatch("CustomViewClicked");
-        if (doc.layoutCustom === undefined) {
-            const width = NumCast(doc.width);
-            const height = NumCast(doc.height);
-            const options = { title: "data", width, x: -width / 2, y: - height / 2, };
+        const customName = "layout-" + name;
+        if (doc[customName] === undefined) {
+            const _width = NumCast(doc.width);
+            const _height = NumCast(doc.height);
+            const options = { title: "data", _width, x: -_width / 2, y: - _height / 2, };
 
             let fieldTemplate: Doc;
             switch (doc.type) {
@@ -549,12 +550,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             fieldTemplate.heading = 1;
             fieldTemplate.autoHeight = true;
 
-            const docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: doc.title + "_layout", width: width + 20, height: Math.max(100, height + 45) });
+            const docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
 
             Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate));
-            Doc.ApplyTemplateTo(docTemplate, dataDoc || doc, "layoutCustom", undefined);
+            Doc.ApplyTemplateTo(docTemplate, dataDoc || doc, customName, undefined);
         } else {
-            doc.layoutKey = "layoutCustom";
+            doc.layoutKey = customName;
         }
         batch.end();
     }
@@ -622,9 +623,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     freezeNativeDimensions = (): void => {
         this.layoutDoc.autoHeight = this.layoutDoc.autoHeight = false;
         this.layoutDoc.ignoreAspect = !this.layoutDoc.ignoreAspect;
-        if (!this.layoutDoc.ignoreAspect && !this.layoutDoc.nativeWidth) {
-            this.layoutDoc.nativeWidth = this.props.PanelWidth();
-            this.layoutDoc.nativeHeight = this.props.PanelHeight();
+        if (!this.layoutDoc.ignoreAspect && !this.layoutDoc._nativeWidth) {
+            this.layoutDoc._nativeWidth = this.props.PanelWidth();
+            this.layoutDoc._nativeHeight = this.props.PanelHeight();
         }
     }
 
@@ -635,7 +636,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (!anchors.find(anchor2 => anchor2 && anchor2.title === this.Document.title + ".portal" ? true : false)) {
             const portalID = (this.Document.title + ".portal").replace(/^-/, "").replace(/\([0-9]*\)$/, "");
             DocServer.GetRefField(portalID).then(existingPortal => {
-                const portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.layoutDoc.width || 0) + 10, height: this.layoutDoc.height || 0, title: portalID });
+                const portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { _width: (this.layoutDoc._width || 0) + 10, _height: this.layoutDoc._height || 0, title: portalID });
                 DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, portalID, "portal link");
                 this.Document.isButton = true;
             });
@@ -646,13 +647,14 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @action
     setNarrativeView = (custom: boolean): void => {
         if (custom) {
-            this.props.Document.layout_narrative = CollectionView.LayoutString("narrative");
-            this.props.Document.nativeWidth = this.props.Document.nativeHeight = undefined;
-            !this.props.Document.narrative && (Doc.GetProto(this.props.Document).narrative = new List<Doc>([]));
-            this.props.Document.viewType = CollectionViewType.Stacking;
-            this.props.Document.layoutKey = "layout_narrative";
-        } else {
-            DocumentView.makeNativeViewClicked(this.props.Document);
+            custom ? DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, "narrative") : DocumentView.makeNativeViewClicked(this.props.Document);
+            //     this.props.Document.layout_narrative = CollectionView.LayoutString("narrative");
+            //     this.props.Document.layoutKey = "layout_narrative";
+            //     this.props.Document._nativeWidth = this.props.Document._nativeHeight = undefined;
+            //     !this.props.Document.narrative && (Doc.GetProto(this.props.Document).narrative = new List<Doc>([]));
+            //     this.props.Document._viewType = CollectionViewType.Stacking;
+            // } else {
+            //     DocumentView.makeNativeViewClicked(this.props.Document);
         }
     }
 
@@ -709,7 +711,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         subitems.push({ description: "Open Right      ", event: () => this.props.addDocTab(this.props.Document, this.props.DataDoc, "onRight", this.props.LibraryPath), icon: "caret-square-right" });
         subitems.push({ description: "Open Alias Tab  ", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "inTab"), icon: "folder" });
         subitems.push({ description: "Open Alias Right", event: () => this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.props.DataDoc, "onRight"), icon: "caret-square-right" });
-        subitems.push({ description: "Open Fields     ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" });
+        subitems.push({ description: "Open Fields     ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), undefined, "onRight"), icon: "layer-group" });
         cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" });
 
 
@@ -737,9 +739,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (this.props.DataDoc) {
             layoutItems.push({ description: "Make View of Metadata Field", event: () => Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.DataDoc!), icon: "concierge-bell" });
         }
-        layoutItems.push({ description: `${this.Document.chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document.chromeStatus = (this.Document.chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
+        layoutItems.push({ description: `${this.Document._chromeStatus !== "disabled" ? "Hide" : "Show"} Chrome`, event: () => this.Document._chromeStatus = (this.Document._chromeStatus !== "disabled" ? "disabled" : "enabled"), icon: "project-diagram" });
         layoutItems.push({ description: `${this.Document.autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc.autoHeight = !this.layoutDoc.autoHeight, icon: "plus" });
-        layoutItems.push({ description: this.Document.ignoreAspect || !this.Document.nativeWidth || !this.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" });
+        layoutItems.push({ description: this.Document.ignoreAspect || !this.Document._nativeWidth || !this.Document._nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" });
         layoutItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
         layoutItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
         layoutItems.push({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
@@ -793,13 +795,13 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                     const mode2 = mode === DocServer.WriteMode.Default ? mode : DocServer.WriteMode.Playground;
                     DocServer.setFieldWriteMode("x", mode1);
                     DocServer.setFieldWriteMode("y", mode1);
-                    DocServer.setFieldWriteMode("width", mode1);
-                    DocServer.setFieldWriteMode("height", mode1);
+                    DocServer.setFieldWriteMode("_width", mode1);
+                    DocServer.setFieldWriteMode("_height", mode1);
 
-                    DocServer.setFieldWriteMode("panX", mode2);
-                    DocServer.setFieldWriteMode("panY", mode2);
+                    DocServer.setFieldWriteMode("_panX", mode2);
+                    DocServer.setFieldWriteMode("_panY", mode2);
                     DocServer.setFieldWriteMode("scale", mode2);
-                    DocServer.setFieldWriteMode("viewType", mode2);
+                    DocServer.setFieldWriteMode("_viewType", mode2);
                 };
                 const aclsMenu: ContextMenuProps[] = [];
                 aclsMenu.push({ description: "Default (write/read all)", event: () => setWriteMode(DocServer.WriteMode.Default), icon: DocServer.AclsMode === DocServer.WriteMode.Default ? "check" : "exclamation" });
@@ -858,7 +860,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const fallback = Cast(this.props.Document.layoutKey, "string");
         return typeof fallback === "string" ? fallback : "layout";
     }
-    childScaling = () => (this.layoutDoc.fitWidth ? this.props.PanelWidth() / this.nativeWidth : this.props.ContentScaling());
+    childScaling = () => (this.layoutDoc._fitWidth ? this.props.PanelWidth() / this._nativeWidth : this.props.ContentScaling());
     @computed get contents() {
         TraceMobx();
         return (<DocumentContentsView ContainingCollectionView={this.props.ContainingCollectionView}
@@ -981,7 +983,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const highlightColors = ["transparent", "maroon", "maroon", "yellow", "magenta", "cyan", "orange"];
         const highlightStyles = ["solid", "dashed", "solid", "solid", "solid", "solid", "solid"];
-        let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc.viewType !== CollectionViewType.Linear;
+        let highlighting = fullDegree && this.layoutDoc.type !== DocumentType.FONTICON && this.layoutDoc._viewType !== CollectionViewType.Linear;
         highlighting = highlighting && this.props.focus !== emptyFunction;  // bcz: hack to turn off highlighting onsidebar panel documents.  need to flag a document as not highlightable in a more direct way
         return <div className={`documentView-node${this.topMost ? "-topmost" : ""}`} ref={this._mainCont} onKeyDown={this.onKeyDown}
             onDrop={this.onDrop} onContextMenu={this.onContextMenu} onPointerDown={this.onPointerDown} onClick={this.onClick}
@@ -993,7 +995,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
                 border: highlighting && borderRounding ? `${highlightStyles[fullDegree]} ${highlightColors[fullDegree]} ${localScale}px` : undefined,
                 boxShadow: this.props.Document.isTemplateForField ? "black 0.2vw 0.2vw 0.8vw" : undefined,
-                background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc.viewType === CollectionViewType.Linear ? undefined : backgroundColor,
+                background: this.layoutDoc.type === DocumentType.FONTICON || this.layoutDoc._viewType === CollectionViewType.Linear ? undefined : backgroundColor,
                 width: animwidth,
                 height: animheight,
                 opacity: this.Document.opacity
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0a1a79bc4..9303ca0fa 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -152,7 +152,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key);
             DocServer.GetRefField(value).then(doc => {
                 DocServer.GetRefField(id).then(linkDoc => {
-                    this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
+                    this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, _width: 500, _height: 500 }, value);
                     DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
                     if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
                     else DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: this.dataDoc[key] as Doc }, "Ref:" + value, "link to named target", id);
@@ -193,8 +193,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
             const tsel = this._editorView.state.selection.$from;
             tsel.marks().filter(m => m.type === this._editorView!.state.schema.marks.user_mark).map(m => AudioBox.SetScrubTime(Math.max(0, m.attrs.modified * 5000 - 1000)));
             this._applyingChange = true;
-            this.extensionDoc && !this.extensionDoc.lastModified && (this.extensionDoc.backgroundColor = "lightGray");
-            this.extensionDoc && (this.extensionDoc.lastModified = new DateField(new Date(Date.now())));
+            this.dataDoc[this.props.fieldKey + "-lastModified"] && (this.dataDoc[this.props.fieldKey + "-backgroundColor"] = "lightGray");
+            this.dataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
             this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()), state.doc.textBetween(0, state.doc.content.size, "\n\n"));
             this._applyingChange = false;
             this.updateTitle();
@@ -271,7 +271,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 const target = de.complete.docDragData.droppedDocuments[0];
                 // const link = DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "Embedded Doc:" + target.title);
                 // if (link) {
-                target.fitToBox = true;
+                target._fitToBox = true;
                 const node = schema.nodes.dashDoc.create({
                     width: target[WidthSym](), height: target[HeightSym](),
                     title: "dashDoc", docid: target[Id],
@@ -704,11 +704,8 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 DocServer.GetRefField(pdfRegionId).then(pdfRegion => {
                     if ((pdfDoc instanceof Doc) && (pdfRegion instanceof Doc)) {
                         setTimeout(async () => {
-                            const extension = Doc.fieldExtensionDoc(pdfDoc, "data");
-                            if (extension) {
-                                const targetAnnotations = await DocListCastAsync(extension.annotations);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
-                                targetAnnotations && targetAnnotations.push(pdfRegion);
-                            }
+                            const targetAnnotations = await DocListCastAsync(pdfDoc["data-annotations"]);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
+                            targetAnnotations && targetAnnotations.push(pdfRegion);
                         });
 
                         const link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
@@ -1069,12 +1066,12 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 this.layoutDoc.limitHeight = undefined;
                 this.layoutDoc.autoHeight = false;
             }
-            const nh = this.Document.isTemplateForField ? 0 : NumCast(this.dataDoc.nativeHeight, 0);
-            const dh = NumCast(this.layoutDoc.height, 0);
+            const nh = this.Document.isTemplateForField ? 0 : NumCast(this.dataDoc._nativeHeight, 0);
+            const dh = NumCast(this.layoutDoc._height, 0);
             const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
             if (Math.abs(newHeight - dh) > 1) { // bcz: Argh!  without this, we get into a React crash if the same document is opened in a freeform view and in the treeview.  no idea why, but after dragging the freeform document, selecting it, and selecting text, it will compute to 1 pixel higher than the treeview which causes a cycle
-                this.layoutDoc.height = newHeight;
-                this.dataDoc.nativeHeight = nh ? scrollHeight : undefined;
+                this.layoutDoc._height = newHeight;
+                this.dataDoc._nativeHeight = nh ? scrollHeight : undefined;
             }
         }
     }
@@ -1082,6 +1079,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
     @computed get sidebarWidthPercent() { return StrCast(this.props.Document.sidebarWidthPercent, "0%"); }
     @computed get sidebarWidth() { return Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); }
     @computed get annotationsKey() { return "annotations"; }
+    @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
     render() {
         TraceMobx();
         const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
@@ -1122,7 +1120,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 {this.props.Document.hideSidebar ? (null) : this.sidebarWidthPercent === "0%" ?
                     <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown} onClick={e => this.toggleSidebar()} /> :
                     <div className={"formattedTextBox-sidebar" + (InkingControl.Instance.selectedTool !== InkTool.None ? "-inking" : "")}
-                        style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${StrCast(this.extensionDoc?.backgroundColor, "transparent")}` }}>
+                        style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
                         <CollectionFreeFormView {...this.props}
                             PanelHeight={this.props.PanelHeight}
                             PanelWidth={() => this.sidebarWidth}
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index 8dedfda9b..fda3e3285 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -86,7 +86,7 @@ export class FormattedTextBoxComment {
                     DocumentManager.Instance.FollowLink(FormattedTextBoxComment.linkDoc, textBox.props.Document,
                         (doc: Doc, maxLocation: string) => textBox.props.addDocTab(doc, undefined, e.ctrlKey ? "inTab" : "onRight"));
                 } else if (textBox && (FormattedTextBoxComment.tooltipText as any).href) {
-                    textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, width: 200, height: 400 }), undefined, "onRight");
+                    textBox.props.addDocTab(Docs.Create.WebDocument((FormattedTextBoxComment.tooltipText as any).href, { title: (FormattedTextBoxComment.tooltipText as any).href, _width: 200, _height: 400 }), undefined, "onRight");
                 }
                 keep && textBox && FormattedTextBoxComment.start !== undefined && textBox.adoptAnnotation(
                     FormattedTextBoxComment.start, FormattedTextBoxComment.end, FormattedTextBoxComment.mark);
diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx
index 9462ff024..172338eb6 100644
--- a/src/client/views/nodes/IconBox.tsx
+++ b/src/client/views/nodes/IconBox.tsx
@@ -79,7 +79,7 @@ export class IconBox extends React.Component<FieldViewProps> {
                 <Measure offset onResize={(r) => runInAction(() => {
                     if (r.offset!.width || this.props.Document.hideLabel) {
                         this.props.Document.iconWidth = (r.offset!.width + Number(MINIMIZED_ICON_SIZE));
-                        if (this.props.Document.height === Number(MINIMIZED_ICON_SIZE)) this.props.Document.width = this.props.Document.iconWidth;
+                        if (this.props.Document._height === Number(MINIMIZED_ICON_SIZE)) this.props.Document._width = this.props.Document.iconWidth;
                     }
                 })}>
                     {({ measureRef }) =>
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index b7e904283..1a07c1598 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -39,7 +39,6 @@ library.add(faFileAudio, faAsterisk);
 export const pageSchema = createSchema({
     curPage: "number",
     fitWidth: "boolean",
-    rotation: "number",
     googlePhotosUrl: "string",
     googlePhotosTags: "string"
 });
@@ -78,7 +77,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 e.stopPropagation();
             }
             de.metaKey && de.complete.docDragData.droppedDocuments.forEach(action((drop: Doc) => {
-                this.extensionDoc && Doc.AddDocToList(Doc.GetProto(this.extensionDoc), "Alternates", drop);
+                Doc.AddDocToList(this.dataDoc, this.props.fieldKey + "-alternates", drop);
                 e.stopPropagation();
             }));
         }
@@ -88,8 +87,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
         let gumStream: any;
         let recorder: any;
         const self = this;
-        const extensionDoc = this.extensionDoc;
-        extensionDoc && navigator.mediaDevices.getUserMedia({
+        navigator.mediaDevices.getUserMedia({
             audio: true
         }).then(function (stream) {
             gumStream = stream;
@@ -104,11 +102,11 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 const files = await res.json();
                 const url = Utils.prepend(files[0].path);
                 // upload to server with known URL 
-                const audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", width: 200, height: 32 });
+                const audioDoc = Docs.Create.AudioDocument(url, { title: "audio test", _width: 200, _height: 32 });
                 audioDoc.treeViewExpandedView = "layout";
-                const audioAnnos = Cast(extensionDoc.audioAnnotations, listSpec(Doc));
+                const audioAnnos = Cast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"], listSpec(Doc));
                 if (audioAnnos === undefined) {
-                    extensionDoc.audioAnnotations = new List([audioDoc]);
+                    this.dataDoc[this.props.fieldKey + "-audioAnnotations"] = new List([audioDoc]);
                 } else {
                     audioAnnos.push(audioDoc);
                 }
@@ -125,15 +123,15 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     @undoBatch
     rotate = action(() => {
-        const nw = this.Document.nativeWidth;
-        const nh = this.Document.nativeHeight;
-        const w = this.Document.width;
-        const h = this.Document.height;
-        this.Document.rotation = ((this.Document.rotation || 0) + 90) % 360;
-        this.Document.nativeWidth = nh;
-        this.Document.nativeHeight = nw;
-        this.Document.width = h;
-        this.Document.height = w;
+        const nw = NumCast(this.Document[this.props.fieldKey + "-nativeWidth"]);
+        const nh = NumCast(this.Document[this.props.fieldKey + "-nativeHeight"]);
+        const w = this.Document._width;
+        const h = this.Document._height;
+        this.dataDoc[this.props.fieldKey + "-rotation"] = (NumCast(this.dataDoc[this.props.fieldKey + "-rotation"]) + 90) % 360;
+        this.dataDoc[this.props.fieldKey + "-nativeWidth"] = nh;
+        this.dataDoc[this.props.fieldKey + "-nativeHeight"] = nw;
+        this.Document._width = h;
+        this.Document._height = w;
     });
 
     specificContextMenu = (e: React.MouseEvent): void => {
@@ -159,7 +157,7 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
             results.reduce((face: CognitiveServices.Image.Face, faceDocs: List<Doc>) => faceDocs.push(Docs.Get.DocumentHierarchyFromJson(face, `Face: ${face.faceId}`)!), new List<Doc>());
             return faceDocs;
         };
-        this.url && this.extensionDoc && CognitiveServices.Image.Appliers.ProcessImage(this.extensionDoc, ["faces"], this.url, Service.Face, converter);
+        this.url && CognitiveServices.Image.Appliers.ProcessImage(this.dataDoc, [this.props.fieldKey + "-faces"], this.url, Service.Face, converter);
     }
 
     generateMetadata = (threshold: Confidence = Confidence.Excellent) => {
@@ -171,12 +169,12 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 const sanitized = tag.name.replace(" ", "_");
                 tagDoc[sanitized] = ComputedField.MakeFunction(`(${tag.confidence} >= this.confidence) ? ${tag.confidence} : "${ComputedField.undefined}"`);
             });
-            this.extensionDoc && (this.extensionDoc.generatedTags = tagsList);
+            this.dataDoc[this.props.fieldKey + "-generatedTags"] = tagsList;
             tagDoc.title = "Generated Tags Doc";
             tagDoc.confidence = threshold;
             return tagDoc;
         };
-        this.url && this.extensionDoc && CognitiveServices.Image.Appliers.ProcessImage(this.extensionDoc, ["generatedTagsDoc"], this.url, Service.ComputerVision, converter);
+        this.url && CognitiveServices.Image.Appliers.ProcessImage(this.dataDoc, [this.props.fieldKey + "-generatedTagsDoc"], this.url, Service.ComputerVision, converter);
     }
 
     @computed private get url() {
@@ -216,29 +214,30 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     _resized = "";
     resize = (imgPath: string) => {
-        requestImageSize(imgPath)
-            .then((size: any) => {
-                const rotation = NumCast(this.dataDoc.rotation) % 180;
-                const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
-                const aspect = realsize.height / realsize.width;
-                if (this.Document.width && (Math.abs(1 - NumCast(this.Document.height) / NumCast(this.Document.width) / (realsize.height / realsize.width)) > 0.1)) {
-                    setTimeout(action(() => {
-                        if (this.paths[NumCast(this.props.Document.curPage)] === imgPath && (!this.layoutDoc.isTemplateDoc || this.dataDoc !== this.layoutDoc)) {
-                            this._resized = imgPath;
-                            this.Document.height = this.Document[WidthSym]() * aspect;
-                            this.Document.nativeHeight = realsize.height;
-                            this.Document.nativeWidth = realsize.width;
-                        }
-                    }), 0);
-                } else this._resized = imgPath;
-            })
-            .catch((err: any) => console.log(err));
+        if (!this.dataDoc[this.props.fieldKey + "-nativeHeight"])
+            requestImageSize(imgPath)
+                .then((size: any) => {
+                    const rotation = NumCast(this.dataDoc[this.props.fieldKey + "-rotation"]) % 180;
+                    const realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
+                    const aspect = realsize.height / realsize.width;
+                    if (this.Document._width && (Math.abs(1 - NumCast(this.Document._height) / NumCast(this.Document._width) / (realsize.height / realsize.width)) > 0.1)) {
+                        setTimeout(action(() => {
+                            if (this.paths[NumCast(this.props.Document.curPage)] === imgPath && (!this.layoutDoc.isTemplateDoc || this.dataDoc !== this.layoutDoc)) {
+                                this._resized = imgPath;
+                                this.Document._height = this.Document[WidthSym]() * aspect;
+                                this.dataDoc[this.props.fieldKey + "-nativeHeight"] = this.dataDoc._nativeHeight = realsize.height;
+                                this.dataDoc[this.props.fieldKey + "-nativeWidth"] = this.dataDoc._nativeWidth = realsize.width;
+                            }
+                        }), 0);
+                    } else this._resized = imgPath;
+                })
+                .catch((err: any) => console.log(err));
     }
 
     @action
     onPointerEnter = () => {
         const self = this;
-        const audioAnnos = this.extensionDoc && DocListCast(this.extensionDoc.audioAnnotations);
+        const audioAnnos = DocListCast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"]);
         if (audioAnnos && audioAnnos.length && this._audioState === 0) {
             const anno = audioAnnos[Math.floor(Math.random() * audioAnnos.length)];
             anno.data instanceof AudioField && new Howl({
@@ -273,17 +272,16 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     @computed get nativeSize() {
         const pw = typeof this.props.PanelWidth === "function" ? this.props.PanelWidth() : typeof this.props.PanelWidth === "number" ? (this.props.PanelWidth as any) as number : 50;
-        const nativeWidth = (this.Document.nativeWidth || pw);
-        const nativeHeight = (this.Document.nativeHeight || 1);
+        const nativeWidth = NumCast(this.dataDoc[this.props.fieldKey + "-nativeWidth"], pw);
+        const nativeHeight = NumCast(this.dataDoc[this.props.fieldKey + "-nativeHeight"], 1);
         return { nativeWidth, nativeHeight };
     }
 
     @computed get paths() {
-        const extensionDoc = this.extensionDoc!;
         let paths = [Utils.CorsProxy("http://www.cs.brown.edu/~bcz/noImage.png")];
         // this._curSuffix = "";
         // if (w > 20) {
-        const alts = DocListCast(extensionDoc.Alternates);
+        const alts = DocListCast(this.dataDoc[this.props.fieldKey + "-alternates"]);
         const altpaths = alts.filter(doc => doc.data instanceof ImageField).map(doc => this.choosePath((doc.data as ImageField).url));
         const field = this.dataDoc[this.props.fieldKey];
         // if (w < 100 && this._smallRetryCount < 10) this._curSuffix = "_s";
@@ -296,13 +294,11 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     @computed get content() {
         TraceMobx();
-        const extensionDoc = this.extensionDoc;
-        if (!extensionDoc) return (null);
 
         const srcpath = this.paths[NumCast(this.props.Document.curPage, 0)];
         const fadepath = this.paths[Math.min(1, this.paths.length - 1)];
         const { nativeWidth, nativeHeight } = this.nativeSize;
-        const rotation = NumCast(this.Document.rotation, 0);
+        const rotation = NumCast(this.dataDoc[this.props.fieldKey + "-rotation"]);
         const aspect = (rotation % 180) ? this.Document[HeightSym]() / this.Document[WidthSym]() : 1;
         const shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
 
@@ -331,10 +327,11 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                 style={{ height: `calc(${.1 * nativeHeight / nativeWidth * 100}%)` }}
             >
                 <FontAwesomeIcon className="imageBox-audioFont"
-                    style={{ color: [DocListCast(extensionDoc.audioAnnotations).length ? "blue" : "gray", "green", "red"][this._audioState] }} icon={!DocListCast(extensionDoc.audioAnnotations).length ? "microphone" : faFileAudio} size="sm" />
+                    style={{ color: [DocListCast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"]).length ? "blue" : "gray", "green", "red"][this._audioState] }}
+                    icon={!DocListCast(this.dataDoc[this.props.fieldKey + "-audioAnnotations"]).length ? "microphone" : faFileAudio} size="sm" />
             </div>
             {this.considerGooglePhotosLink()}
-            <FaceRectangles document={extensionDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
+            <FaceRectangles document={this.dataDoc} color={"#0000FF"} backgroundColor={"#0000FF"} />
         </div>;
     }
 
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 234a6a9d3..499cd2877 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -179,7 +179,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
     }
 
     getTemplate = async () => {
-        const parent = Docs.Create.StackingDocument([], { width: 800, height: 800, title: "Template" });
+        const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template" });
         parent.singleColumn = false;
         parent.columnWidth = 100;
         for (const row of this.rows.filter(row => row.isChecked)) {
@@ -200,15 +200,15 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
         if (!fieldTemplate) {
             return;
         }
-        const previousViewType = fieldTemplate.viewType;
+        const previousViewType = fieldTemplate._viewType;
         Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(parentStackingDoc));
-        previousViewType && (fieldTemplate.viewType = previousViewType);
+        previousViewType && (fieldTemplate._viewType = previousViewType);
 
         Cast(parentStackingDoc.data, listSpec(Doc))!.push(fieldTemplate);
     }
 
     inferType = async (data: FieldResult, metaKey: string) => {
-        const options = { width: 300, height: 300, title: metaKey };
+        const options = { _width: 300, _height: 300, title: metaKey };
         if (data instanceof RichTextField || typeof data === "string" || typeof data === "number") {
             return Docs.Create.TextDocument(options);
         } else if (data instanceof List) {
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 46466aa0f..e6b512adf 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -46,7 +46,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
         if (value instanceof Doc) {
             e.stopPropagation();
             e.preventDefault();
-            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(value, { width: 300, height: 300 }), undefined, "onRight"), icon: "layer-group" });
+            ContextMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(value, { _width: 300, _height: 300 }), undefined, "onRight"), icon: "layer-group" });
             ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
         }
     }
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 8370df6ba..49fdf56e6 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -50,9 +50,9 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     constructor(props: any) {
         super(props);
         this._initialScale = this.props.ScreenToLocalTransform().Scale;
-        const nw = this.Document.nativeWidth = NumCast(this.extensionDocSync.nativeWidth, NumCast(this.Document.nativeWidth, 927));
-        const nh = this.Document.nativeHeight = NumCast(this.extensionDocSync.nativeHeight, NumCast(this.Document.nativeHeight, 1200));
-        !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
+        const nw = this.Document._nativeWidth = NumCast(this.dataDoc[this.props.fieldKey + "-nativeWidth"], NumCast(this.Document._nativeWidth, 927));
+        const nh = this.Document._nativeHeight = NumCast(this.dataDoc[this.props.fieldKey + "-nativeHeight"], NumCast(this.Document._nativeHeight, 1200));
+        !this.Document._fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
 
         const backup = "oldPath";
         const { Document } = this.props;
@@ -90,10 +90,10 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     }
 
     loaded = (nw: number, nh: number, np: number) => {
-        this.extensionDocSync.numPages = np;
-        this.extensionDocSync.nativeWidth = this.Document.nativeWidth = nw * 96 / 72;
-        this.extensionDocSync.nativeHeight = this.Document.nativeHeight = nh * 96 / 72;
-        !this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
+        this.dataDoc[this.props.fieldKey + "-numPages"] = np;
+        this.dataDoc[this.props.fieldKey + "-nativeWidth"] = this.Document._nativeWidth = nw * 96 / 72;
+        this.dataDoc[this.props.fieldKey + "-nativeHeight"] = this.Document._nativeHeight = nh * 96 / 72;
+        !this.Document._fitWidth && !this.Document.ignoreAspect && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
     }
 
     public search(string: string, fwd: boolean) { this._pdfViewer && this._pdfViewer.search(string, fwd); }
@@ -211,7 +211,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
         const funcs: ContextMenuProps[] = [];
         pdfUrl && funcs.push({ description: "Copy path", event: () => Utils.CopyText(pdfUrl.url.pathname), icon: "expand-arrows-alt" });
-        funcs.push({ description: "Toggle Fit Width " + (this.Document.fitWidth ? "Off" : "On"), event: () => this.Document.fitWidth = !this.Document.fitWidth, icon: "expand-arrows-alt" });
+        funcs.push({ description: "Toggle Fit Width " + (this.Document._fitWidth ? "Off" : "On"), event: () => this.Document._fitWidth = !this.Document._fitWidth, icon: "expand-arrows-alt" });
 
         ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" });
     }
@@ -220,8 +220,8 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     @computed get renderTitleBox() {
         const classname = "pdfBox" + (this.active() ? "-interactive" : "");
         return <div className={classname} style={{
-            width: !this.props.Document.fitWidth ? this.Document.nativeWidth || 0 : `${100 / this.contentScaling}%`,
-            height: !this.props.Document.fitWidth ? this.Document.nativeHeight || 0 : `${100 / this.contentScaling}%`,
+            width: !this.props.Document._fitWidth ? this.Document._nativeWidth || 0 : `${100 / this.contentScaling}%`,
+            height: !this.props.Document._fitWidth ? this.Document._nativeHeight || 0 : `${100 / this.contentScaling}%`,
             transform: `scale(${this.contentScaling})`
         }}  >
             <div className="pdfBox-title-outer">
@@ -252,7 +252,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
     render() {
         const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField, null);
         if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true;
-        if (pdfUrl && this.extensionDoc && (this._everActive || (this.extensionDoc.nativeWidth && this.props.ScreenToLocalTransform().Scale < 2.5))) {
+        if (pdfUrl && (this._everActive || (this.dataDoc[this.props.fieldKey + "-nativeWidth"] && this.props.ScreenToLocalTransform().Scale < 2.5))) {
             if (pdfUrl instanceof PdfField && this._pdf) {
                 return this.renderPdfView;
             }
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 1e6894f37..eda12d6fb 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -336,7 +336,7 @@ export class PresBox extends React.Component<FieldViewProps> {
      */
     @action
     initializeScaleViews = (docList: Doc[], viewtype: number) => {
-        this.props.Document.chromeStatus = "disabled";
+        this.props.Document._chromeStatus = "disabled";
         const hgt = (viewtype === CollectionViewType.Tree) ? 50 : 72;
         docList.forEach((doc: Doc) => {
             doc.presBox = this.props.Document;
@@ -360,7 +360,7 @@ export class PresBox extends React.Component<FieldViewProps> {
         return this.props.ScreenToLocalTransform().translate(-10, -50);// listBox padding-left and pres-box-cont minHeight
     }
     render() {
-        this.initializeScaleViews(this.childDocs, NumCast(this.props.Document.viewType));
+        this.initializeScaleViews(this.childDocs, NumCast(this.props.Document._viewType));
         return (
             <div className="presBox-cont" onContextMenu={this.specificContextMenu}>
                 <div className="presBox-buttons">
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 52b4f391a..066c51654 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -55,12 +55,12 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
 
     videoLoad = () => {
         const aspect = this.player!.videoWidth / this.player!.videoHeight;
-        const nativeWidth = (this.Document.nativeWidth || 0);
-        const nativeHeight = (this.Document.nativeHeight || 0);
+        const nativeWidth = (this.Document._nativeWidth || 0);
+        const nativeHeight = (this.Document._nativeHeight || 0);
         if (!nativeWidth || !nativeHeight) {
-            if (!this.Document.nativeWidth) this.Document.nativeWidth = this.player!.videoWidth;
-            this.Document.nativeHeight = (this.Document.nativeWidth || 0) / aspect;
-            this.Document.height = (this.Document.width || 0) / aspect;
+            if (!this.Document._nativeWidth) this.Document._nativeWidth = this.player!.videoWidth;
+            this.Document._nativeHeight = (this.Document._nativeWidth || 0) / aspect;
+            this.Document._height = (this.Document._width || 0) / aspect;
         }
         if (!this.Document.duration) this.Document.duration = this.player!.duration;
     }
@@ -101,11 +101,11 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
     }
 
     @action public Snapshot() {
-        const width = this.Document.width || 0;
-        const height = this.Document.height || 0;
+        const width = this.Document._width || 0;
+        const height = this.Document._height || 0;
         const canvas = document.createElement('canvas');
         canvas.width = 640;
-        canvas.height = 640 * (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1);
+        canvas.height = 640 * (this.Document._nativeHeight || 0) / (this.Document._nativeWidth || 1);
         const ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions
         if (ctx) {
             ctx.rect(0, 0, canvas.width, canvas.height);
@@ -117,7 +117,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         if (!this._videoRef) { // can't find a way to take snapshots of videos
             const b = Docs.Create.ButtonDocument({
                 x: (this.Document.x || 0) + width, y: (this.Document.y || 0),
-                width: 150, height: 50, title: (this.Document.currentTimecode || 0).toString()
+                _width: 150, _height: 50, title: (this.Document.currentTimecode || 0).toString()
             });
             b.onClick = ScriptField.MakeScript(`this.currentTimecode = ${(this.Document.currentTimecode || 0)}`);
         } else {
@@ -130,7 +130,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
                     const url = this.choosePath(Utils.prepend(returnedFilename));
                     const imageSummary = Docs.Create.ImageDocument(url, {
                         x: (this.Document.x || 0) + width, y: (this.Document.y || 0),
-                        width: 150, height: height / width * 150, title: "--snapshot" + (this.Document.currentTimecode || 0) + " image-"
+                        _width: 150, _height: height / width * 150, title: "--snapshot" + (this.Document.currentTimecode || 0) + " image-"
                     });
                     imageSummary.isButton = true;
                     this.props.addDocument && this.props.addDocument(imageSummary);
@@ -151,12 +151,12 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
 
         if (this.youtubeVideoId) {
             const youtubeaspect = 400 / 315;
-            const nativeWidth = (this.Document.nativeWidth || 0);
-            const nativeHeight = (this.Document.nativeHeight || 0);
+            const nativeWidth = (this.Document._nativeWidth || 0);
+            const nativeHeight = (this.Document._nativeHeight || 0);
             if (!nativeWidth || !nativeHeight) {
-                if (!this.Document.nativeWidth) this.Document.nativeWidth = 600;
-                this.Document.nativeHeight = (this.Document.nativeWidth || 0) / youtubeaspect;
-                this.Document.height = (this.Document.width || 0) / youtubeaspect;
+                if (!this.Document._nativeWidth) this.Document._nativeWidth = 600;
+                this.Document._nativeHeight = (this.Document._nativeWidth || 0) / youtubeaspect;
+                this.Document._height = (this.Document._width || 0) / youtubeaspect;
             }
         }
     }
@@ -321,7 +321,7 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
         const style = "videoBox-content-YouTube" + (this._fullScreen ? "-fullScreen" : "");
         const start = untracked(() => Math.round(this.Document.currentTimecode || 0));
         return <iframe key={this._youtubeIframeId} id={`${this.youtubeVideoId + this._youtubeIframeId}-player`}
-            onLoad={this.youtubeIframeLoaded} className={`${style}`} width={(this.Document.nativeWidth || 640)} height={(this.Document.nativeHeight || 390)}
+            onLoad={this.youtubeIframeLoaded} className={`${style}`} width={(this.Document._nativeWidth || 640)} height={(this.Document._nativeHeight || 390)}
             src={`https://www.youtube.com/embed/${this.youtubeVideoId}?enablejsapi=1&rel=0&showinfo=1&autoplay=1&mute=1&start=${start}&modestbranding=1&controls=${VideoBox._showControls ? 1 : 0}`} />;
     }
 
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f21f9ff46..102db8810 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -39,12 +39,12 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
         const field = Cast(this.props.Document[this.props.fieldKey], WebField);
         if (field && field.url.href.indexOf("youtube") !== -1) {
             const youtubeaspect = 400 / 315;
-            const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
-            const nativeHeight = NumCast(this.layoutDoc.nativeHeight);
+            const nativeWidth = NumCast(this.layoutDoc._nativeWidth);
+            const nativeHeight = NumCast(this.layoutDoc._nativeHeight);
             if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) {
-                if (!nativeWidth) this.layoutDoc.nativeWidth = 600;
-                this.layoutDoc.nativeHeight = NumCast(this.layoutDoc.nativeWidth) / youtubeaspect;
-                this.layoutDoc.height = NumCast(this.layoutDoc.width) / youtubeaspect;
+                if (!nativeWidth) this.layoutDoc._nativeWidth = 600;
+                this.layoutDoc._nativeHeight = NumCast(this.layoutDoc._nativeWidth) / youtubeaspect;
+                this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect;
             }
         }
 
@@ -87,8 +87,8 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
             x: NumCast(this.props.Document.x),
             y: NumCast(this.props.Document.y),
             title: url,
-            width: 200,
-            height: 70,
+            _width: 200,
+            _height: 70,
             documentText: "@@@" + url
         });
 
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 6599c0e3c..d8b340db6 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -11,10 +11,11 @@ import "./Annotation.scss";
 
 interface IAnnotationProps {
     anno: Doc;
-    extensionDoc: Doc;
     addDocTab: (document: Doc, dataDoc: Opt<Doc>, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     focus: (doc: Doc) => void;
+    dataDoc: Doc;
+    fieldKey: string;
 }
 
 export default class Annotation extends React.Component<IAnnotationProps> {
@@ -29,10 +30,11 @@ interface IRegionAnnotationProps {
     y: number;
     width: number;
     height: number;
-    extensionDoc: Doc;
     addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
     pinToPres: (document: Doc) => void;
     document: Doc;
+    dataDoc: Doc;
+    fieldKey: string;
 }
 
 @observer
@@ -62,12 +64,12 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
     }
 
     deleteAnnotation = () => {
-        const annotation = DocListCast(this.props.extensionDoc.annotations);
+        const annotation = DocListCast(this.props.dataDoc[this.props.fieldKey + "-annotations"]);
         const group = FieldValue(Cast(this.props.document.group, Doc));
         if (group) {
             if (annotation.indexOf(group) !== -1) {
                 const newAnnotations = annotation.filter(a => a !== FieldValue(Cast(this.props.document.group, Doc)));
-                this.props.extensionDoc.annotations = new List<Doc>(newAnnotations);
+                this.props.dataDoc[this.props.fieldKey + "-annotations"] = new List<Doc>(newAnnotations);
             }
 
             DocListCast(group.annotations).forEach(anno => anno.delete = true);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index d6829937e..a00d2a7f4 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -113,8 +113,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     private _coverPath: any;
 
     @computed get allAnnotations() {
-        return this.extensionDoc ? DocListCast(this.extensionDoc.annotations).filter(
-            anno => this._script.run({ this: anno }, console.log, true).result) : [];
+        return DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]).filter(
+            anno => this._script.run({ this: anno }, console.log, true).result);
     }
 
     @computed get nonDocAnnotations() {
@@ -208,8 +208,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         await this.initialLoad();
 
         this._annotationReactionDisposer = reaction(
-            () => this.extensionDoc && DocListCast(this.extensionDoc.annotations),
-            annotations => annotations && annotations.length && (this._annotations = annotations),
+            () => DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]),
+            annotations => annotations?.length && (this._annotations = annotations),
             { fireImmediately: true });
 
         this._filterReactionDisposer = reaction(
@@ -271,8 +271,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
             const annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: color, title: "Annotation on " + this.Document.title });
             if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
             if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
-            if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
-            if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
+            if (anno.style.height) annoDoc._height = parseInt(anno.style.height);
+            if (anno.style.width) annoDoc._width = parseInt(anno.style.width);
             annoDoc.group = mainAnnoDoc;
             annoDoc.isButton = true;
             annoDocs.push(annoDoc);
@@ -286,8 +286,8 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
                 const annoDoc = new Doc();
                 if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
                 if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
-                if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
-                if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
+                if (anno.style.height) annoDoc._height = parseInt(anno.style.height);
+                if (anno.style.width) annoDoc._width = parseInt(anno.style.width);
                 annoDoc.group = mainAnnoDoc;
                 annoDoc.backgroundColor = color;
                 annoDocs.push(annoDoc);
@@ -558,7 +558,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     startDrag = (e: PointerEvent, ele: HTMLElement): void => {
         e.preventDefault();
         e.stopPropagation();
-        const targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
+        const targetDoc = Docs.Create.TextDocument({ _width: 200, _height: 200, title: "Note linked to " + this.props.Document.title });
         const annotationDoc = this.highlight("rgba(146, 245, 95, 0.467)"); // yellowish highlight color when dragging out a text selection
         if (annotationDoc) {
             DragManager.StartPdfAnnoDrag([ele], new DragManager.PdfAnnoDragData(this.props.Document, annotationDoc, targetDoc), e.pageX, e.pageY, {
@@ -573,11 +573,11 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         const data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
         data.title = StrCast(data.title) + "_snippet";
         view.proto = data;
-        view.nativeHeight = marquee.height;
-        view.height = (this.Document[WidthSym]() / (this.Document.nativeWidth || 1)) * marquee.height;
-        view.nativeWidth = this.Document.nativeWidth;
+        view._nativeHeight = marquee.height;
+        view._height = (this.Document[WidthSym]() / (this.Document._nativeWidth || 1)) * marquee.height;
+        view._nativeWidth = this.Document._nativeWidth;
         view.startY = marquee.top;
-        view.width = this.Document[WidthSym]();
+        view._width = this.Document[WidthSym]();
         DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0);
     }
 
@@ -598,12 +598,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     getCoverImage = () => {
         if (!this.props.Document[HeightSym]() || !this.props.Document.nativeHeight) {
             setTimeout((() => {
-                this.Document.height = this.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
-                this.Document.nativeHeight = (this.Document.nativeWidth || 0) * this._coverPath.height / this._coverPath.width;
+                this.Document._height = this.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
+                this.Document._nativeHeight = (this.Document._nativeWidth || 0) * this._coverPath.height / this._coverPath.width;
             }).bind(this), 0);
         }
-        const nativeWidth = (this.Document.nativeWidth || 0);
-        const nativeHeight = (this.Document.nativeHeight || 0);
+        const nativeWidth = (this.Document._nativeWidth || 0);
+        const nativeHeight = (this.Document._nativeHeight || 0);
         const resolved = Utils.prepend(this._coverPath.path);
         return <img key={resolved} src={resolved} onError={action(() => this._coverPath.path = "http://www.cs.brown.edu/~bcz/face.gif")} onLoad={action(() => this._showWaiting = false)}
             style={{ position: "absolute", display: "inline-block", top: 0, left: 0, width: `${nativeWidth}px`, height: `${nativeHeight}px` }} />;
@@ -623,12 +623,12 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
         TraceMobx();
         return <div className="pdfViewer-annotationLayer" style={{ height: (this.Document.nativeHeight || 0), transform: `scale(${this._zoomed})` }} ref={this._annotationLayer}>
             {this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
-                <Annotation {...this.props} focus={this.props.focus} extensionDoc={this.extensionDoc!} anno={anno} key={`${anno[Id]}-annotation`} />)}
+                <Annotation {...this.props} focus={this.props.focus} dataDoc={this.dataDoc!} fieldKey={this.props.fieldKey} anno={anno} key={`${anno[Id]}-annotation`} />)}
         </div>;
     }
     overlayTransform = () => this.scrollXf().scale(1 / this._zoomed);
-    panelWidth = () => (this.Document.scrollHeight || this.Document.nativeHeight || 0);
-    panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document.nativeWidth || 0);
+    panelWidth = () => (this.Document.scrollHeight || this.Document._nativeHeight || 0);
+    panelHeight = () => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : (this.Document._nativeWidth || 0);
     @computed get overlayLayer() {
         return <div className={`pdfViewer-overlay${InkingControl.Instance.selectedTool !== InkTool.None ? "-inking" : ""}`} id="overlay" style={{ transform: `scale(${this._zoomed})` }}>
             <CollectionFreeFormView {...this.props}
@@ -675,20 +675,19 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
     contentZoom = () => this._zoomed;
     render() {
         TraceMobx();
-        return !this.extensionDoc ? (null) :
-            <div className={"pdfViewer" + (this._zoomed !== 1 ? "-zoomed" : "")} ref={this._mainCont}
-                onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
-                style={{
-                    width: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeWidth) : `${100 / this.contentScaling}%`,
-                    height: !this.props.Document.fitWidth ? NumCast(this.props.Document.nativeHeight) : `${100 / this.contentScaling}%`,
-                    transform: `scale(${this.props.ContentScaling()})`
-                }}  >
-                {this.pdfViewerDiv}
-                {this.overlayLayer}
-                {this.annotationLayer}
-                {this.standinViews}
-                <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
-            </div >;
+        return <div className={"pdfViewer" + (this._zoomed !== 1 ? "-zoomed" : "")} ref={this._mainCont}
+            onScroll={this.onScroll} onWheel={this.onZoomWheel} onPointerDown={this.onPointerDown} onClick={this.onClick}
+            style={{
+                width: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeWidth) : `${100 / this.contentScaling}%`,
+                height: !this.props.Document._fitWidth ? NumCast(this.props.Document._nativeHeight) : `${100 / this.contentScaling}%`,
+                transform: `scale(${this.props.ContentScaling()})`
+            }}  >
+            {this.pdfViewerDiv}
+            {this.overlayLayer}
+            {this.annotationLayer}
+            {this.standinViews}
+            <PdfViewerMarquee isMarqueeing={this.marqueeing} width={this.marqueeWidth} height={this.marqueeHeight} x={this.marqueeX} y={this.marqueeY} />
+        </div >;
     }
 }
 
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 92dc0f3d2..dad55e1fd 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -161,12 +161,12 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
             return (null);
         }
 
-        const propDocWidth = NumCast(this.layoutDoc.nativeWidth);
-        const propDocHeight = NumCast(this.layoutDoc.nativeHeight);
-        const scale = () => 175 / NumCast(this.layoutDoc.nativeWidth, 175);
+        const propDocWidth = NumCast(this.layoutDoc._nativeWidth);
+        const propDocHeight = NumCast(this.layoutDoc._nativeHeight);
+        const scale = () => 175 / NumCast(this.layoutDoc._nativeWidth, 175);
         return (
             <div className="presElementBox-embedded" style={{
-                height: propDocHeight === 0 ? NumCast(this.layoutDoc.height) - NumCast(this.layoutDoc.collapsedHeight) : propDocHeight * scale(),
+                height: propDocHeight === 0 ? NumCast(this.layoutDoc._height) - NumCast(this.layoutDoc.collapsedHeight) : propDocHeight * scale(),
                 width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
             }}>
                 <ContentFittingDocumentView
@@ -192,7 +192,7 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
     }
 
     render() {
-        const treecontainer = this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.viewType === CollectionViewType.Tree;
+        const treecontainer = this.props.ContainingCollectionDoc?._viewType === CollectionViewType.Tree;
         const className = "presElementBox-item" + (this.currentIndex === this.indexInPres ? " presElementBox-selected" : "");
         const pbi = "presElementBox-interaction";
         return (
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index f7ae83b2f..be13dae03 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -217,16 +217,16 @@ export class SearchBox extends React.Component {
             doc.x = x;
             doc.y = y;
             const size = 200;
-            const aspect = NumCast(doc.nativeHeight) / NumCast(doc.nativeWidth, 1);
+            const aspect = NumCast(doc._nativeHeight) / NumCast(doc._nativeWidth, 1);
             if (aspect > 1) {
-                doc.height = size;
-                doc.width = size / aspect;
+                doc._height = size;
+                doc._width = size / aspect;
             } else if (aspect > 0) {
-                doc.width = size;
-                doc.height = size * aspect;
+                doc._width = size;
+                doc._height = size * aspect;
             } else {
-                doc.width = size;
-                doc.height = size;
+                doc._width = size;
+                doc._height = size;
             }
             x += 250;
             if (x > 1000) {
@@ -234,7 +234,7 @@ export class SearchBox extends React.Component {
                 y += 300;
             }
         }
-        return Docs.Create.TreeDocument(docs, { width: 200, height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
+        return Docs.Create.TreeDocument(docs, { _width: 200, _height: 400, backgroundColor: "grey", title: `Search Docs: "${this._searchString}"` });
     }
 
     @action.bound
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 21a4560cf..8aea737f0 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -68,11 +68,11 @@ export class SelectorContextMenu extends React.Component<SearchItemProps> {
     getOnClick({ col, target }: { col: Doc, target: Doc }) {
         return () => {
             col = Doc.IsPrototype(col) ? Doc.MakeDelegate(col) : col;
-            if (NumCast(col.viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
-                const newPanX = NumCast(target.x) + NumCast(target.width) / 2;
-                const newPanY = NumCast(target.y) + NumCast(target.height) / 2;
-                col.panX = newPanX;
-                col.panY = newPanY;
+            if (NumCast(col._viewType, CollectionViewType.Invalid) === CollectionViewType.Freeform) {
+                const newPanX = NumCast(target.x) + NumCast(target._width) / 2;
+                const newPanY = NumCast(target.y) + NumCast(target._height) / 2;
+                col._panX = newPanX;
+                col._panY = newPanY;
             }
             CollectionDockingView.AddRightSplit(col, undefined);
         };
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index 0b0280519..dab4de110 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -55,7 +55,7 @@ class Uploader extends React.Component {
                     const json = await res.json();
                     json.map(async (file: any) => {
                         const path = window.location.origin + file;
-                        const doc = Docs.Create.ImageDocument(path, { nativeWidth: 200, width: 200, title: name });
+                        const doc = Docs.Create.ImageDocument(path, { _nativeWidth: 200, _width: 200, title: name });
 
                         this.status = "getting user document";
 
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 4b7f10f91..16f67d419 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -162,8 +162,8 @@ export class Doc extends RefField {
 
     private [Self] = this;
     private [SelfProxy]: any;
-    public [WidthSym] = () => NumCast(this[SelfProxy].width);
-    public [HeightSym] = () => NumCast(this[SelfProxy].height);
+    public [WidthSym] = () => NumCast(this[SelfProxy]._width);
+    public [HeightSym] = () => NumCast(this[SelfProxy]._height);
 
     [ToScriptString]() {
         return "invalid";
@@ -447,19 +447,18 @@ export namespace Doc {
         if (!WillExpandTemplateLayout(templateLayoutDoc, dataDoc) || !dataDoc) return templateLayoutDoc;
 
         const templateField = StrCast(templateLayoutDoc.isTemplateForField);  // the field that the template renders
-        const extensionDoc = fieldExtensionDoc(dataDoc, templateField); // an extension doc for the field that the template renders
         // First it checks if an expanded layout already exists -- if so it will be stored on the dataDoc
         // using the template layout doc's id as the field key.
         // If it doesn't find the expanded layout, then it makes a delegate of the template layout and
         // saves it on the data doc indexed by the template layout's id.
         //
-        const expandedLayoutFieldKey = "Layout[" + templateLayoutDoc[Id] + "]";
-        const expandedTemplateLayout = extensionDoc?.[expandedLayoutFieldKey];
-        if (expandedTemplateLayout === undefined && extensionDoc) {
+        const expandedLayoutFieldKey = templateField + "-layout[" + templateLayoutDoc[Id] + "]";
+        const expandedTemplateLayout = dataDoc?.[expandedLayoutFieldKey];
+        if (expandedTemplateLayout === undefined) {
             setTimeout(() => {
-                if (!extensionDoc[expandedLayoutFieldKey]) {
+                if (!dataDoc[expandedLayoutFieldKey]) {
                     const newLayoutDoc = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]");
-                    extensionDoc[expandedLayoutFieldKey] = newLayoutDoc;
+                    dataDoc[expandedLayoutFieldKey] = newLayoutDoc;
                     newLayoutDoc.resolvedDataDoc = dataDoc;
                 }
             }, 0);
@@ -473,26 +472,6 @@ export namespace Doc {
         const resolvedDataDoc = containerDataDoc === containerDoc || !containerDataDoc ? undefined : Doc.GetDataDoc(containerDataDoc);
         return { layout: Doc.expandTemplateLayout(childDoc, resolvedDataDoc), data: resolvedDataDoc };
     }
-
-    //
-    // Resolves a reference to a field by returning 'doc' if no field extension is specified,
-    // otherwise, it returns the extension document stored in doc.<fieldKey>_ext.
-    // This mechanism allows any fields to be extended with an extension document that can
-    // be used to capture field-specific metadata.  For example, an image field can be extended
-    // to store annotations, ink, and other data.
-    //
-    export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
-        if (!fieldKey) return undefined;
-        const extension = doc[fieldKey + "_ext"];
-        if (doc instanceof Doc && extension === undefined) {
-            setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
-        }
-        return extension ? extension as Doc : undefined;
-    }
-    export function fieldExtensionDocSync(doc: Doc, fieldKey: string) {
-        return (doc[fieldKey + "_ext"] as Doc) || CreateDocumentExtensionForField(doc, fieldKey);
-    }
-
     export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
         let proto: Doc | undefined = doc;
         while (proto && !Doc.IsPrototype(proto) && proto.proto) {
@@ -586,8 +565,8 @@ export namespace Doc {
     export function ApplyTemplateTo(templateDoc: Doc, target: Doc, targetKey: string, titleTarget: string | undefined = undefined) {
         if (!templateDoc) {
             target.layout = undefined;
-            target.nativeWidth = undefined;
-            target.nativeHeight = undefined;
+            target._nativeWidth = undefined;
+            target._nativeHeight = undefined;
             target.onClick = undefined;
             target.type = undefined;
             return;
@@ -648,12 +627,12 @@ export namespace Doc {
         const doc1Layout = Doc.Layout(doc1);
         const x2 = NumCast(doc2.x) - clusterDistance;
         const y2 = NumCast(doc2.y) - clusterDistance;
-        const w2 = NumCast(doc2Layout.width) + clusterDistance;
-        const h2 = NumCast(doc2Layout.height) + clusterDistance;
+        const w2 = NumCast(doc2Layout._width) + clusterDistance;
+        const h2 = NumCast(doc2Layout._height) + clusterDistance;
         const x = NumCast(doc1.x) - clusterDistance;
         const y = NumCast(doc1.y) - clusterDistance;
-        const w = NumCast(doc1Layout.width) + clusterDistance;
-        const h = NumCast(doc1Layout.height) + clusterDistance;
+        const w = NumCast(doc1Layout._width) + clusterDistance;
+        const h = NumCast(doc1Layout._height) + clusterDistance;
         return doc1.z === doc2.z && intersectRect({ left: x, top: y, width: w, height: h }, { left: x2, top: y2, width: w2, height: h2 });
     }
 
@@ -812,7 +791,7 @@ Scripting.addGlobal(function matchFieldValue(doc: Doc, key: string, value: any)
     return fieldStr == value;
 });
 Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, modifiers?: string) {
-    const docFilters = Cast(container.docFilter, listSpec("string"), []);
+    const docFilters = Cast(container._docFilter, listSpec("string"), []);
     for (let i = 0; i < docFilters.length; i += 3) {
         if (docFilters[i] === key && docFilters[i + 1] === value) {
             docFilters.splice(i, 3);
@@ -823,7 +802,7 @@ Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: an
         docFilters.push(key);
         docFilters.push(value)
         docFilters.push(modifiers);
-        container.docFilter = new List<string>(docFilters);
+        container._docFilter = new List<string>(docFilters);
     }
     const docFilterText = Doc.MakeDocFilter(docFilters);
     container.viewSpecScript = docFilterText ? ScriptField.MakeFunction(docFilterText, { doc: Doc.name }) : undefined;
diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts
index 682206aa2..6f34c82db 100644
--- a/src/new_fields/RichTextUtils.ts
+++ b/src/new_fields/RichTextUtils.ts
@@ -273,7 +273,7 @@ export namespace RichTextUtils {
             const guid = Utils.GenerateDeterministicGuid(src);
             const backingDocId = StrCast(textNote[guid]);
             if (!backingDocId) {
-                const backingDoc = Docs.Create.ImageDocument(src, { width: 300, height: 300 });
+                const backingDoc = Docs.Create.ImageDocument(src, { _width: 300, _height: 300 });
                 DocumentView.makeCustomViewClicked(backingDoc, undefined);
                 docid = backingDoc[Id];
                 textNote[guid] = docid;
diff --git a/src/new_fields/documentSchemas.ts b/src/new_fields/documentSchemas.ts
index 180c52b3d..44ba6d65c 100644
--- a/src/new_fields/documentSchemas.ts
+++ b/src/new_fields/documentSchemas.ts
@@ -8,16 +8,18 @@ export const documentSchema = createSchema({
     layoutKey: "string",        // holds the field key for the field that actually holds the current lyoat
     layoutCustom: Doc,          // used to hold a custom layout (there's nothing special about this field .. any field could hold a custom layout that can be selected by setting 'layoutKey')
     title: "string",            // document title (can be on either data document or layout)
-    nativeWidth: "number",      // native width of document which determines how much document contents are scaled when the document's width is set
-    nativeHeight: "number",     // "
-    width: "number",            // width of document in its container's coordinate system
-    height: "number",           // "
+    _dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias" or "copy")
+    _nativeWidth: "number",      // native width of document which determines how much document contents are scaled when the document's width is set
+    _nativeHeight: "number",     // "
+    _width: "number",            // width of document in its container's coordinate system
+    _height: "number",           // "
+    _freeformLayoutEngine: "string",// the string ID for the layout engine to use to layout freeform view documents
+    _LODdisable: "boolean",      // whether to disbale LOD switching for CollectionFreeFormViews
     color: "string",            // foreground color of document
     backgroundColor: "string",  // background color of document
     opacity: "number",          // opacity of document
     creationDate: DateField,     // when the document was created
     links: listSpec(Doc),       // computed (readonly) list of links associated with this document
-    dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias" or "copy")
     removeDropProperties: listSpec("string"), // properties that should be removed from the alias/copy/etc of this document when it is dropped
     onClick: ScriptField,       // script to run when document is clicked (can be overriden by an onClick prop)
     onPointerDown: ScriptField,       // script to run when document is clicked (can be overriden by an onClick prop)
@@ -56,7 +58,6 @@ export const documentSchema = createSchema({
     xPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     yPadding: "number",         // pixels of padding on left/right of collectionfreeformview contents when fitToBox is set
     LODarea: "number",          // area (width*height) where CollectionFreeFormViews switch from a label to rendering contents
-    LODdisable: "boolean",      // whether to disbale LOD switching for CollectionFreeFormViews
     letterSpacing: "string",
     textTransform: "string"
 });
diff --git a/src/new_fields/util.ts b/src/new_fields/util.ts
index 3255c6172..7d093b6ea 100644
--- a/src/new_fields/util.ts
+++ b/src/new_fields/util.ts
@@ -7,6 +7,7 @@ import { ObjectField } from "./ObjectField";
 import { action, trace } from "mobx";
 import { Parent, OnUpdate, Update, Id, SelfProxy, Self } from "./FieldSymbols";
 import { DocServer } from "../client/DocServer";
+import { props } from "bluebird";
 
 function _readOnlySetter(): never {
     throw new Error("Documents can't be modified in read-only mode");
@@ -35,6 +36,7 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
         target[prop] = value;
         return true;
     }
+
     if (typeof prop === "symbol") {
         target[prop] = value;
         return true;
@@ -98,11 +100,39 @@ export function makeEditable() {
     _setter = _setterImpl;
 }
 
-export function setter(target: any, prop: string | symbol | number, value: any, receiver: any): boolean {
+let layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHeight", "fitWidth", "fitToBox",
+    "LODdisable", "dropAction", "chromeStatus", "viewType", "gridGap", "xMargin", "yMargin"];
+export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
+    let prop = in_prop;
+    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" &&
+        ((prop as string).startsWith("_") || layoutProps.includes(prop))) {
+        if (!prop.startsWith("_")) {
+            console.log(prop + " is deprecated - switch to _" + prop);
+            prop = "_" + prop;
+        }
+        const resolvedLayout = getFieldImpl(target, getFieldImpl(target, "layoutKey", receiver), receiver); // + "-" + (prop as string).substring(1);
+        if (resolvedLayout instanceof Doc) {
+            resolvedLayout[prop] = value;
+            return true;
+        }
+    }
     return _setter(target, prop, value, receiver);
 }
 
-export function getter(target: any, prop: string | symbol | number, receiver: any): any {
+export function getter(target: any, in_prop: string | symbol | number, receiver: any): any {
+    let prop = in_prop;
+    if (typeof prop === "string" && prop !== "__id" && prop !== "__fields" &&
+        ((prop as string).startsWith("_") || layoutProps.includes(prop))) {
+        if (!prop.startsWith("_")) {
+            console.log(prop + " is deprecated - switch to _" + prop);
+            prop = "_" + prop;
+        }
+        const resolvedLayout = getFieldImpl(target, getFieldImpl(target, "layoutKey", receiver), receiver); // + "-" + (prop as string).substring(1);
+        if (resolvedLayout instanceof Doc) {
+            return resolvedLayout[prop];
+        }
+        // prop = getFieldImpl(target, "layoutKey", receiver) + "-" + (prop as string).substring(1);
+    }
     if (prop === "then") {//If we're being awaited
         return undefined;
     }
diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py
index c7b795bbd..f16bbfd14 100644
--- a/src/scraping/buxton/scraper.py
+++ b/src/scraping/buxton/scraper.py
@@ -85,13 +85,14 @@ def write_collection(parse_results, display_fields, storage_key, viewType):
             "proto": protofy(data_doc["_id"]),
             "x": 10,
             "y": 10,
-            "width": 900,
-            "height": 600,
-            "panX": 0,
-            "panY": 0,
+            "_width": 900,
+            "_height": 600,
+            "_panX": 0,
+            "_panY": 0,
             "zIndex": 2,
             "libraryBrush": False,
-            "viewType": viewType
+            "_viewType": viewType,
+            "_LODdisable": True
         },
         "__type": "Doc"
     }
@@ -100,9 +101,8 @@ def write_collection(parse_results, display_fields, storage_key, viewType):
     fields[storage_key] = listify(proxify_guids(view_guids))
     fields["schemaColumns"] = listify(display_fields)
     fields["backgroundColor"] = "white"
-    fields["viewType"] = 2
+    fields["_viewType"] = 2
     fields["author"] = "Bill Buxton"
-    fields["LODdisable"] = True
     fields["creationDate"] = {
         "date": datetime.datetime.utcnow().microsecond,
         "__type": "date"
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 406d71085..361cf9216 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -44,18 +44,18 @@ export class CurrentUserUtils {
     // setup the "creator" buttons for the sidebar-- eg. the default set of draggable document creation tools
     static setupCreatorButtons(doc: Doc, buttons?: string[]) {
         const notes = CurrentUserUtils.setupNoteTypes(doc);
-        doc.noteTypes = Docs.Create.TreeDocument(notes, { title: "Note Types", height: 75 });
+        doc.noteTypes = Docs.Create.TreeDocument(notes, { title: "Note Types", _height: 75 });
         doc.activePen = doc;
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, click?: string, ischecked?: string, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
-            { title: "collection", icon: "folder", ignoreClick: true, drag: 'Docs.Create.FreeformDocument([], { nativeWidth: undefined, nativeHeight: undefined, LODdisable: true, width: 150, height: 100, title: "freeform" })' },
-            { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), { width: 250, height: 250, title: "container" })' },
+            { title: "collection", icon: "folder", ignoreClick: true, drag: 'Docs.Create.FreeformDocument([], { _nativeWidth: undefined, _nativeHeight: undefined, _LODdisable: true, _width: 150, _height: 100, title: "freeform" })' },
+            { title: "preview", icon: "expand", ignoreClick: true, drag: 'Docs.Create.DocumentDocument(ComputedField.MakeFunction("selectedDocs(this,true,[_last_])?.[0]"), { _width: 250, _height: 250, title: "container" })' },
             { title: "todo item", icon: "check", ignoreClick: true, drag: 'getCopy(this.dragFactory, true)', dragFactory: notes[notes.length - 1] },
-            { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", { width: 300, height: 300, title: "New Webpage" })' },
-            { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { width: 200, title: "an image of a cat" })' },
-            { title: "record", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { width: 200, title: "ready to record audio" })` },
-            { title: "clickable button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ width: 150, height: 50, title: "Button" })' },
-            { title: "presentation", icon: "tv", ignoreClick: true, drag: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { width: 200, height: 500, title: "a presentation trail" })' },
-            { title: "import folder", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", width: 400, height: 400 })' },
+            { title: "web page", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.WebDocument("https://en.wikipedia.org/wiki/Hedgehog", {_width: 300, _height: 300, title: "New Webpage" })' },
+            { title: "cat image", icon: "cat", ignoreClick: true, drag: 'Docs.Create.ImageDocument("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg", { _width: 200, title: "an image of a cat" })' },
+            { title: "record", icon: "microphone", ignoreClick: true, drag: `Docs.Create.AudioDocument("${nullAudio}", { _width: 200, title: "ready to record audio" })` },
+            { title: "clickable button", icon: "bolt", ignoreClick: true, drag: 'Docs.Create.ButtonDocument({ _width: 150, _height: 50, title: "Button" })' },
+            { title: "presentation", icon: "tv", ignoreClick: true, drag: 'Doc.UserDoc().curPresentation = Docs.Create.PresDocument(new List<Doc>(), { _width: 200, _height: 500, title: "a presentation trail" })' },
+            { title: "import folder", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' },
             { title: "mobile view", icon: "phone", ignoreClick: true, drag: 'Doc.UserDoc().activeMobile' },
             { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.pen,  this)`, activePen: doc },
             { title: "use highlighter", icon: "highlighter", click: 'activateBrush(this.activePen.pen = sameDocs(this.activePen.pen, this) ? undefined : this,20,this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
@@ -65,7 +65,7 @@ export class CurrentUserUtils {
             { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "white", activePen: doc },
         ];
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
-            nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
+            _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, _dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
             onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
             ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activePen: data.activePen,
             backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
@@ -103,7 +103,7 @@ export class CurrentUserUtils {
             { title: "use drag", icon: "mouse-pointer", click: 'deactivateInk();this.activePen.pen = this;', ischecked: `sameDocs(this.activePen.pen, this)`, backgroundColor: "white", activePen: doc },
         ];
         return docProtoData.filter(d => !buttons || !buttons.includes(d.title)).map(data => Docs.Create.FontIconDocument({
-            nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
+            _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, _dropAction: data.click ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
             onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined, onClick: data.click ? ScriptField.MakeScript(data.click) : undefined,
             ischecked: data.ischecked ? ComputedField.MakeFunction(data.ischecked) : undefined, activePen: data.activePen,
             backgroundColor: data.backgroundColor, removeDropProperties: new List<string>(["dropAction"]), dragFactory: data.dragFactory,
@@ -114,11 +114,11 @@ export class CurrentUserUtils {
         const docProtoData: { title: string, icon: string, drag?: string, ignoreClick?: boolean, pointerDown?: string, pointerUp?: string, ischecked?: string, clipboard?: Doc, activePen?: Doc, backgroundColor?: string, dragFactory?: Doc }[] = [
             { title: "use pen", icon: "pen-nib", pointerUp: "resetPen()", pointerDown: 'setPen(2, this.backgroundColor)', backgroundColor: "blue", ischecked: `sameDocs(this.activePen.pen,  this)`, activePen: doc },
             { title: "use highlighter", icon: "highlighter", pointerUp: "resetPen()", pointerDown: 'setPen(20, this.backgroundColor)', backgroundColor: "yellow", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
-            { title: "notepad", icon: "clipboard", pointerUp: "GestureOverlay.Instance.closeFloatingDoc()", pointerDown: 'GestureOverlay.Instance.openFloatingDoc(this.clipboard)', clipboard: Docs.Create.FreeformDocument([], { width: 300, height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
-            { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", clipboard: Docs.Create.FreeformDocument([], { width: 300, height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
+            { title: "notepad", icon: "clipboard", pointerUp: "GestureOverlay.Instance.closeFloatingDoc()", pointerDown: 'GestureOverlay.Instance.openFloatingDoc(this.clipboard)', clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
+            { title: "interpret text", icon: "font", pointerUp: "setToolglass('none')", pointerDown: "setToolglass('inktotext')", clipboard: Docs.Create.FreeformDocument([], { _width: 300, _height: 300 }), backgroundColor: "orange", ischecked: `sameDocs(this.activePen.pen, this)`, activePen: doc },
         ];
         return docProtoData.map(data => Docs.Create.FontIconDocument({
-            nativeWidth: 10, nativeHeight: 10, width: 10, height: 10, dropAction: data.pointerDown ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
+            _nativeWidth: 10, _nativeHeight: 10, _width: 10, _height: 10, _dropAction: data.pointerDown ? "copy" : undefined, title: data.title, icon: data.icon, ignoreClick: data.ignoreClick,
             onDragStart: data.drag ? ScriptField.MakeFunction(data.drag) : undefined,
             clipboard: data.clipboard,
             onPointerUp: data.pointerUp ? ScriptField.MakeScript(data.pointerUp) : undefined, onPointerDown: data.pointerDown ? ScriptField.MakeScript(data.pointerDown) : undefined,
@@ -130,7 +130,7 @@ export class CurrentUserUtils {
     static setupThumbDoc(userDoc: Doc) {
         if (!userDoc.thumbDoc) {
             userDoc.thumbDoc = Docs.Create.LinearDocument(CurrentUserUtils.setupThumbButtons(userDoc), {
-                width: 100, height: 50, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons", autoHeight: true, yMargin: 5, isExpanded: true, backgroundColor: "white"
+                _width: 100, _height: 50, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", autoHeight: true, _yMargin: 5, isExpanded: true, backgroundColor: "white"
             });
         }
         return userDoc.thumbDoc;
@@ -138,7 +138,7 @@ export class CurrentUserUtils {
 
     static setupMobileDoc(userDoc: Doc) {
         return userDoc.activeMoble ?? Docs.Create.MasonryDocument(CurrentUserUtils.setupMobileButtons(userDoc), {
-            columnWidth: 100, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons", autoHeight: true, yMargin: 5
+            columnWidth: 100, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons", autoHeight: true, _yMargin: 5
         });
     }
 
@@ -146,19 +146,19 @@ export class CurrentUserUtils {
     static setupToolsPanel(sidebarContainer: Doc, doc: Doc) {
         // setup a masonry view of all he creators
         const dragCreators = Docs.Create.MasonryDocument(CurrentUserUtils.setupCreatorButtons(doc), {
-            width: 500, autoHeight: true, columnWidth: 35, ignoreClick: true, lockedPosition: true, chromeStatus: "disabled", title: "buttons",
-            dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), yMargin: 5
+            _width: 500, autoHeight: true, columnWidth: 35, ignoreClick: true, lockedPosition: true, _chromeStatus: "disabled", title: "buttons",
+            dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name }), _yMargin: 5
         });
         // setup a color picker
         const color = Docs.Create.ColorDocument({
-            title: "color picker", width: 300, dropAction: "alias", forceActive: true, removeDropProperties: new List<string>(["dropAction", "forceActive"])
+            title: "color picker", _width: 300, _dropAction: "alias", forceActive: true, removeDropProperties: new List<string>(["dropAction", "forceActive"])
         });
 
         return Docs.Create.ButtonDocument({
-            width: 35, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Tools", fontSize: 10, targetContainer: sidebarContainer,
+            _width: 35, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Tools", fontSize: 10, targetContainer: sidebarContainer,
             letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.StackingDocument([dragCreators, color], {
-                width: 500, lockedPosition: true, chromeStatus: "disabled", title: "tools stack"
+                _width: 500, lockedPosition: true, _chromeStatus: "disabled", title: "tools stack"
             }),
             onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel"),
         });
@@ -168,23 +168,23 @@ export class CurrentUserUtils {
     static setupLibraryPanel(sidebarContainer: Doc, doc: Doc) {
         // setup workspaces library item
         doc.workspaces = Docs.Create.TreeDocument([], {
-            title: "WORKSPACES", height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, backgroundColor: "#eeeeee"
+            title: "WORKSPACES", _height: 100, forceActive: true, boxShadow: "0 0", lockedPosition: true, backgroundColor: "#eeeeee"
         });
 
         doc.documents = Docs.Create.TreeDocument([], {
-            title: "DOCUMENTS", height: 42, forceActive: true, boxShadow: "0 0", preventTreeViewOpen: true, lockedPosition: true, backgroundColor: "#eeeeee"
+            title: "DOCUMENTS", _height: 42, forceActive: true, boxShadow: "0 0", preventTreeViewOpen: true, lockedPosition: true, backgroundColor: "#eeeeee"
         });
 
         // setup Recently Closed library item
         doc.recentlyClosed = Docs.Create.TreeDocument([], {
-            title: "RECENTLY CLOSED", height: 75, forceActive: true, boxShadow: "0 0", preventTreeViewOpen: true, lockedPosition: true, backgroundColor: "#eeeeee"
+            title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", preventTreeViewOpen: true, lockedPosition: true, backgroundColor: "#eeeeee"
         });
 
         return Docs.Create.ButtonDocument({
-            width: 50, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Library", fontSize: 10,
+            _width: 50, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Library", fontSize: 10,
             letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.TreeDocument([doc.workspaces as Doc, doc.documents as Doc, doc.recentlyClosed as Doc], {
-                title: "Library", xMargin: 5, yMargin: 5, gridGap: 5, forceActive: true, dropAction: "alias", lockedPosition: true, boxShadow: "0 0",
+                title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, _dropAction: "alias", lockedPosition: true, boxShadow: "0 0",
             }),
             targetContainer: sidebarContainer,
             onClick: ScriptField.MakeScript("this.targetContainer.proto = this.sourcePanel;")
@@ -194,7 +194,7 @@ export class CurrentUserUtils {
     // setup the Search button which will display the search panel.  
     static setupSearchPanel(sidebarContainer: Doc) {
         return Docs.Create.ButtonDocument({
-            width: 50, height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Search", fontSize: 10,
+            _width: 50, _height: 25, backgroundColor: "lightgrey", color: "rgb(34, 34, 34)", title: "Search", fontSize: 10,
             letterSpacing: "0px", textTransform: "unset", borderRounding: "5px 5px 0px 0px", boxShadow: "3px 3px 0px rgb(34, 34, 34)",
             sourcePanel: Docs.Create.QueryDocument({
                 title: "search stack", ignoreClick: true
@@ -208,7 +208,7 @@ export class CurrentUserUtils {
     // setup the list of sidebar mode buttons which determine what is displayed in the sidebar
     static setupSidebarButtons(doc: Doc) {
         doc.sidebarContainer = new Doc();
-        (doc.sidebarContainer as Doc).chromeStatus = "disabled";
+        (doc.sidebarContainer as Doc)._chromeStatus = "disabled";
         (doc.sidebarContainer as Doc).onClick = ScriptField.MakeScript("freezeSidebar()");
 
         doc.ToolsBtn = this.setupToolsPanel(doc.sidebarContainer as Doc, doc);
@@ -217,21 +217,21 @@ export class CurrentUserUtils {
 
         // Finally, setup the list of buttons to display in the sidebar
         doc.sidebarButtons = Docs.Create.StackingDocument([doc.SearchBtn as Doc, doc.LibraryBtn as Doc, doc.ToolsBtn as Doc], {
-            width: 500, height: 80, boxShadow: "0 0", sectionFilter: "title", hideHeadings: true, ignoreClick: true,
-            backgroundColor: "rgb(100, 100, 100)", chromeStatus: "disabled", title: "library stack",
-            yMargin: 10,
+            _width: 500, _height: 80, boxShadow: "0 0", sectionFilter: "title", hideHeadings: true, ignoreClick: true,
+            backgroundColor: "rgb(100, 100, 100)", _chromeStatus: "disabled", title: "library stack",
+            _yMargin: 10,
         });
     }
 
     /// sets up the default list of buttons to be shown in the expanding button menu at the bottom of the Dash window
     static setupExpandingButtons(doc: Doc) {
         doc.undoBtn = Docs.Create.FontIconDocument(
-            { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("undo()"), removeDropProperties: new List<string>(["dropAction"]), title: "undo button", icon: "undo-alt" });
+            { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, _dropAction: "alias", onClick: ScriptField.MakeScript("undo()"), removeDropProperties: new List<string>(["dropAction"]), title: "undo button", icon: "undo-alt" });
         doc.redoBtn = Docs.Create.FontIconDocument(
-            { nativeWidth: 100, nativeHeight: 100, width: 100, height: 100, dropAction: "alias", onClick: ScriptField.MakeScript("redo()"), removeDropProperties: new List<string>(["dropAction"]), title: "redo button", icon: "redo-alt" });
+            { _nativeWidth: 100, _nativeHeight: 100, _width: 100, _height: 100, _dropAction: "alias", onClick: ScriptField.MakeScript("redo()"), removeDropProperties: new List<string>(["dropAction"]), title: "redo button", icon: "redo-alt" });
 
         doc.expandingButtons = Docs.Create.LinearDocument([doc.undoBtn as Doc, doc.redoBtn as Doc], {
-            title: "expanding buttons", gridGap: 5, xMargin: 5, yMargin: 5, height: 42, width: 100, boxShadow: "0 0",
+            title: "expanding buttons", _gridGap: 5, _xMargin: 5, _yMargin: 5, _height: 42, _width: 100, boxShadow: "0 0",
             backgroundColor: "black", preventTreeViewOpen: true, forceActive: true, lockedPosition: true,
             dropConverter: ScriptField.MakeScript("convertToButtons(dragData)", { dragData: DragManager.DocumentDragData.name })
         });
@@ -240,7 +240,7 @@ export class CurrentUserUtils {
     // sets up the default set of documents to be shown in the Overlay layer
     static setupOverlays(doc: Doc) {
         doc.overlays = Docs.Create.FreeformDocument([], { title: "Overlays", backgroundColor: "#aca3a6" });
-        doc.linkFollowBox = Docs.Create.LinkFollowBoxDocument({ x: 250, y: 20, width: 500, height: 370, title: "Link Follower" });
+        doc.linkFollowBox = Docs.Create.LinkFollowBoxDocument({ x: 250, y: 20, _width: 500, _height: 370, title: "Link Follower" });
         Doc.AddDocToList(doc.overlays as Doc, "data", doc.linkFollowBox as Doc);
     }
 
-- 
cgit v1.2.3-70-g09d2


From 2fac43821ee90ef914c79923b63425aefcdc8e39 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 24 Jan 2020 22:29:31 -0500
Subject: fixes for imagebox's and detailed view

---
 src/client/util/type_decls.d                            |  1 +
 src/client/views/collections/CollectionStackingView.tsx |  4 ++--
 src/client/views/collections/CollectionTreeView.tsx     | 10 ++++++++--
 src/client/views/nodes/FormattedTextBox.tsx             |  7 ++++---
 src/client/views/nodes/ImageBox.tsx                     | 17 +++++++++++------
 src/new_fields/Doc.ts                                   |  3 +++
 6 files changed, 29 insertions(+), 13 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/util/type_decls.d b/src/client/util/type_decls.d
index 622e10960..127f7b798 100644
--- a/src/client/util/type_decls.d
+++ b/src/client/util/type_decls.d
@@ -131,6 +131,7 @@ interface Promise<T> {
 declare const Update: unique symbol;
 declare const Self: unique symbol;
 declare const SelfProxy: unique symbol;
+declare const DataSym: unique symbol;
 declare const HandleUpdate: unique symbol;
 declare const Id: unique symbol;
 declare const OnUpdate: unique symbol;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 55fba2d11..80f78a71c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -4,7 +4,7 @@ import { CursorProperty } from "csstype";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import Switch from 'rc-switch';
-import { Doc, HeightSym, WidthSym } from "../../../new_fields/Doc";
+import { Doc, HeightSym, WidthSym, DataSym } from "../../../new_fields/Doc";
 import { Id } from "../../../new_fields/FieldSymbols";
 import { List } from "../../../new_fields/List";
 import { listSpec } from "../../../new_fields/Schema";
@@ -63,7 +63,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
             const style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
-                {this.getDisplayDoc(d, (d.resolvedDataDoc as Doc) || d, dxf, width)}
+                {this.getDisplayDoc(d, d[DataSym], dxf, width)}
             </div>;
         });
     }
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 6c6e6b449..485abf8b9 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -637,13 +637,19 @@ export class CollectionTreeView extends CollectionSubView(Document) {
 
                 const detailedLayout = Docs.Create.StackingDocument([
                     ImageDocument(fallbackImg, { title: "activeHero" }),
-                    MulticolumnDocument([], { title: "data", _height: 100, onChildClick: ScriptField.MakeFunction(`containingCollection.resolvedDataDoc.activeHero = copyField(this.data)`, { containingCollection: Doc.name }) }),
+                    MulticolumnDocument([], {
+                        title: "data", _height: 100, onChildClick: ScriptField.MakeFunction(
+                            `containingCollection.resolvedDataDoc.activeHero = copyField(this.data);
+                        containingCollection.resolvedDataDoc.activeHero["activeHero-nativeWidth"] = copyField(this.data["data-nativeWidth"]);
+                        containingCollection.resolvedDataDoc.activeHero["activeHero-nativeHeight"] = copyField(this.data["data-nativeHeight"]);
+                        `, { containingCollection: Doc.name })
+                    }),
                     TextDocument({ title: "short_description", _autoHeight: true }),
                     ...["year", "company", "degrees_of_freedom"].map(key => TextDocument({ title: key, _height: 30 }))
                 ], { _chromeStatus: "disabled", title: "detailed layout stack" });
                 detailedLayout.isTemplateDoc = makeTemplate(detailedLayout);
 
-                const cardLayout = ImageDocument(fallbackImg, { isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
+                const cardLayout = ImageDocument(fallbackImg, { title: "cardLayout", isTemplateDoc: true, isTemplateForField: "hero", }); // this acts like a template doc and a template field ... a little weird, but seems to work?
                 cardLayout.proto!.layout = ImageBox.LayoutString("hero");
                 cardLayout.showTitle = "title";
                 cardLayout.showTitleHover = "titlehover";
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 46000a03d..b794ad0c5 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -12,7 +12,7 @@ import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from "
 import { ReplaceStep } from 'prosemirror-transform';
 import { EditorView } from "prosemirror-view";
 import { DateField } from '../../../new_fields/DateField';
-import { Doc, DocListCastAsync, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc";
+import { Doc, DocListCastAsync, Opt, WidthSym, HeightSym, DataSym } from "../../../new_fields/Doc";
 import { Copy, Id } from '../../../new_fields/FieldSymbols';
 import { RichTextField } from "../../../new_fields/RichTextField";
 import { RichTextUtils } from '../../../new_fields/RichTextUtils';
@@ -696,8 +696,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps &
                 DocServer.GetRefField(pdfRegionId).then(pdfRegion => {
                     if ((pdfDoc instanceof Doc) && (pdfRegion instanceof Doc)) {
                         setTimeout(async () => {
-                            const targetAnnotations = await DocListCastAsync(pdfDoc["data-annotations"]);// bcz: NO... this assumes the pdf is using its 'data' field.  need to have the PDF's view handle updating its own annotations
-                            targetAnnotations && targetAnnotations.push(pdfRegion);
+                            const targetField = Doc.LayoutFieldKey(pdfDoc);
+                            const targetAnnotations = await DocListCastAsync(pdfDoc[DataSym][targetField + "-annotations"]);// bcz: better to have the PDF's view handle updating its own annotations
+                            targetAnnotations?.push(pdfRegion);
                         });
 
                         const link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 29b0e912d..8db66d367 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -4,7 +4,7 @@ import { faAsterisk, faFileAudio, faImage, faPaintBrush } from '@fortawesome/fre
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, runInAction, trace } from 'mobx';
 import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym } from '../../../new_fields/Doc';
+import { Doc, DocListCast, HeightSym, WidthSym, DataSym } from '../../../new_fields/Doc';
 import { List } from '../../../new_fields/List';
 import { createSchema, listSpec, makeInterface } from '../../../new_fields/Schema';
 import { ComputedField } from '../../../new_fields/ScriptField';
@@ -24,10 +24,11 @@ import "./ImageBox.scss";
 import React = require("react");
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
 import { documentSchema } from '../../../new_fields/documentSchemas';
-import { Id } from '../../../new_fields/FieldSymbols';
+import { Id, Copy } from '../../../new_fields/FieldSymbols';
 import { TraceMobx } from '../../../new_fields/util';
 import { SelectionManager } from '../../util/SelectionManager';
 import { cache } from 'sharp';
+import { ObjectField } from '../../../new_fields/ObjectField';
 const requestImageSize = require('../../util/request-image-size');
 const path = require('path');
 const { Howl } = require('howler');
@@ -79,8 +80,12 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
                     e.stopPropagation();
                 }));
             } else if (de.altKey || !this.dataDoc[this.props.fieldKey]) {
-                if (de.complete.docDragData.draggedDocuments?.[0].data instanceof ImageField) {
-                    this.dataDoc[this.props.fieldKey] = new ImageField(de.complete.docDragData.draggedDocuments[0].data.url);
+                const layoutDoc = de.complete.docDragData?.draggedDocuments[0];
+                const targetField = Doc.LayoutFieldKey(layoutDoc);
+                if (layoutDoc?.[DataSym][targetField] instanceof ImageField) {
+                    this.dataDoc[this.props.fieldKey] = ObjectField.MakeCopy(layoutDoc[DataSym][targetField] as ImageField);
+                    this.dataDoc[this.props.fieldKey + "-nativeWidth"] = NumCast(layoutDoc[DataSym][targetField + "-nativeWidth"]);
+                    this.dataDoc[this.props.fieldKey + "-nativeHeight"] = NumCast(layoutDoc[DataSym][targetField + "-nativeHeight"]);
                     e.stopPropagation();
                 }
             }
@@ -218,8 +223,8 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
 
     resize = (imgPath: string) => {
         const cachedNativeSize = {
-            width: NumCast(this.Document[this.props.fieldKey + "-nativeWidth"]),
-            height: NumCast(this.Document[this.props.fieldKey + "-nativeHeight"])
+            width: NumCast(this.dataDoc[this.props.fieldKey + "-nativeWidth"]),
+            height: NumCast(this.dataDoc[this.props.fieldKey + "-nativeHeight"])
         };
         const cachedImgPath = this.dataDoc[this.props.fieldKey + "-imgPath"];
         if (!cachedNativeSize.width || !cachedNativeSize.height || imgPath !== cachedImgPath) {
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 913b4f9e5..cc146a121 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -87,6 +87,7 @@ export function DocListCast(field: FieldResult): Doc[] {
 
 export const WidthSym = Symbol("Width");
 export const HeightSym = Symbol("Height");
+export const DataSym = Symbol("Data");
 export const UpdatingFromServer = Symbol("UpdatingFromServer");
 const CachedUpdates = Symbol("Cached updates");
 
@@ -164,6 +165,7 @@ export class Doc extends RefField {
     private [SelfProxy]: any;
     public [WidthSym] = () => NumCast(this[SelfProxy]._width);
     public [HeightSym] = () => NumCast(this[SelfProxy]._height);
+    public get [DataSym]() { return Cast(this[SelfProxy].resolvedDataDoc, Doc, null) || this[SelfProxy]; }
 
     [ToScriptString]() {
         return "invalid";
@@ -659,6 +661,7 @@ export namespace Doc {
     export function Layout(doc: Doc) { return Doc.LayoutField(doc) instanceof Doc ? Doc.LayoutField(doc) as Doc : doc; }
     export function SetLayout(doc: Doc, layout: Doc | string) { doc[StrCast(doc.layoutKey, "layout")] = layout; }
     export function LayoutField(doc: Doc) { return doc[StrCast(doc.layoutKey, "layout")]; }
+    export function LayoutFieldKey(doc: Doc) { return StrCast(Doc.Layout(doc).layout).split("'")[1]; }
     const manager = new DocData();
     export function SearchQuery(): string { return manager._searchQuery; }
     export function SetSearchQuery(query: string) { runInAction(() => manager._searchQuery = query); }
-- 
cgit v1.2.3-70-g09d2


From 30b0762dbce03e314fafd228d457e841be4ec857 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 28 Jan 2020 12:08:01 -0500
Subject: template rendering fixes for stacking view.

---
 src/client/views/collections/CollectionStackingView.tsx |  7 +------
 src/client/views/collections/CollectionTreeView.tsx     |  3 ---
 src/client/views/nodes/ContentFittingDocumentView.tsx   |  2 --
 src/client/views/nodes/DocumentView.tsx                 | 14 +++++---------
 4 files changed, 6 insertions(+), 20 deletions(-)

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 80f78a71c..41247c1b3 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -63,7 +63,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
             const style = this.isStackingView ? { width: width(), marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
-                {this.getDisplayDoc(d, d[DataSym], dxf, width)}
+                {this.getDisplayDoc(d, Cast(d.resolvedDataDoc, Doc, null) || this.props.DataDoc, dxf, width)}
             </div>;
         });
     }
@@ -151,10 +151,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         this.createDashEventsTarget(ele!); //so the whole grid is the drop target?
     }
 
-    overlays = (doc: Doc) => {
-        return doc.type === DocumentType.IMG || doc.type === DocumentType.VID ? { title: StrCast(this.props.Document.showTitles), titleHover: StrCast(this.props.Document.showTitleHovers), caption: StrCast(this.props.Document.showCaptions) } : {};
-    }
-
     @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
     @computed get onClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
@@ -165,7 +161,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             Document={doc}
             DataDocument={dataDoc}
             LibraryPath={this.props.LibraryPath}
-            showOverlays={this.overlays}
             renderDepth={this.props.renderDepth + 1}
             fitToBox={this.props.fitToBox}
             onClick={layoutDoc.isTemplateDoc ? this.onClickHandler : this.onChildClickHandler}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index a54449638..6927f2856 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -323,8 +323,6 @@ class TreeView extends React.Component<TreeViewProps> {
         return rows;
     }
 
-    noOverlays = (doc: Doc) => ({ title: "", caption: "" });
-
     @computed get renderContent() {
         const expandKey = this.treeViewExpandedView === this.fieldKey ? this.fieldKey : this.treeViewExpandedView === "links" ? "links" : undefined;
         if (expandKey !== undefined) {
@@ -351,7 +349,6 @@ class TreeView extends React.Component<TreeViewProps> {
                     DataDocument={this.templateDataDoc}
                     LibraryPath={emptyPath}
                     renderDepth={this.props.renderDepth + 1}
-                    showOverlays={this.noOverlays}
                     fitToBox={this.boundsOfCollectionDocument !== undefined}
                     PanelWidth={this.docWidth}
                     PanelHeight={this.docHeight}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 4f1bbd33c..fa571426d 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -25,7 +25,6 @@ interface ContentFittingDocumentViewProps {
     PanelWidth: () => number;
     PanelHeight: () => number;
     focus?: (doc: Doc) => void;
-    showOverlays?: (doc: Doc) => { title?: string, caption?: string };
     CollectionView?: CollectionView;
     CollectionDoc?: Doc;
     onClick?: ScriptField;
@@ -96,7 +95,6 @@ export class ContentFittingDocumentView extends React.Component<ContentFittingDo
                         LibraryPath={this.props.LibraryPath}
                         fitToBox={this.props.fitToBox}
                         onClick={this.props.onClick}
-                        showOverlays={this.props.showOverlays}
                         addDocument={this.props.addDocument}
                         removeDocument={this.props.removeDocument}
                         moveDocument={this.props.moveDocument}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 30ff975b7..3c625ced5 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -70,7 +70,6 @@ export interface DocumentViewProps {
     moveDocument?: (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean) => boolean;
     ScreenToLocalTransform: () => Transform;
     renderDepth: number;
-    showOverlays?: (doc: Doc) => { title?: string, titleHover?: string, caption?: string };
     ContentScaling: () => number;
     PanelWidth: () => number;
     PanelHeight: () => number;
@@ -846,9 +845,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); };
 
     chromeHeight = () => {
-        const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
-        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.layoutDoc.showTitle);
-        const showTitleHover = showOverlays && "titleHover" in showOverlays ? showOverlays.titleHover : StrCast(this.layoutDoc.showTitleHover);
+        const showTitle = StrCast(this.layoutDoc.showTitle);
+        const showTitleHover = StrCast(this.layoutDoc.showTitleHover);
         return (showTitle && !showTitleHover ? 0 : 0) + 1;
     }
 
@@ -874,7 +872,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             moveDocument={this.props.moveDocument}
             ScreenToLocalTransform={this.props.ScreenToLocalTransform}
             renderDepth={this.props.renderDepth}
-            showOverlays={this.props.showOverlays}
             ContentScaling={this.childScaling}
             PanelWidth={this.props.PanelWidth}
             PanelHeight={this.props.PanelHeight}
@@ -907,10 +904,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @computed get innards() {
         TraceMobx();
-        const showOverlays = this.props.showOverlays ? this.props.showOverlays(this.Document) : undefined;
-        const showTitle = showOverlays && "title" in showOverlays ? showOverlays.title : StrCast(this.getLayoutPropStr("showTitle"));
-        const showTitleHover = showOverlays && "titleHover" in showOverlays ? showOverlays.titleHover : StrCast(this.getLayoutPropStr("showTitleHover"));
-        const showCaption = showOverlays && "caption" in showOverlays ? showOverlays.caption : this.getLayoutPropStr("showCaption");
+        const showTitle = StrCast(this.getLayoutPropStr("showTitle"));
+        const showTitleHover = StrCast(this.getLayoutPropStr("showTitleHover"));
+        const showCaption = this.getLayoutPropStr("showCaption");
         const showTextTitle = showTitle && StrCast(this.layoutDoc.layout).indexOf("FormattedTextBox") !== -1 ? showTitle : undefined;
         const searchHighlight = (!this.Document.searchFields ? (null) :
             <div className="documentView-searchHighlight">
-- 
cgit v1.2.3-70-g09d2


From 7c27e6502037caf1aee3eb9e30b4e0572ce095a1 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Wed, 29 Jan 2020 17:06:59 -0500
Subject: added custom narrative types. fixed scrolling ambiguity with
 stackviews.  can create metdata from stackingview

---
 .../apis/google_docs/GooglePhotosClientUtils.ts    |  2 +-
 src/client/util/ClientUtils.ts.temp                |  3 +
 src/client/views/ContextMenu.tsx                   | 16 ++++-
 src/client/views/TemplateMenu.tsx                  | 33 ++++++---
 .../views/collections/CollectionStackingView.scss  |  2 +-
 .../views/collections/CollectionStackingView.tsx   |  3 +-
 .../CollectionStackingViewFieldColumn.tsx          | 24 ++++++-
 src/client/views/nodes/DocumentView.tsx            | 84 +++++++++-------------
 src/new_fields/RichTextUtils.ts                    |  4 +-
 9 files changed, 104 insertions(+), 67 deletions(-)
 create mode 100644 src/client/util/ClientUtils.ts.temp

(limited to 'src/client/views/collections/CollectionStackingView.tsx')

diff --git a/src/client/apis/google_docs/GooglePhotosClientUtils.ts b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
index 21cd20e14..7e5d5fe1b 100644
--- a/src/client/apis/google_docs/GooglePhotosClientUtils.ts
+++ b/src/client/apis/google_docs/GooglePhotosClientUtils.ts
@@ -340,7 +340,7 @@ export namespace GooglePhotos {
                 const url = data.url.href;
                 const target = Doc.MakeAlias(source);
                 const description = parseDescription(target, descriptionKey);
-                await DocumentView.makeCustomViewClicked(target, undefined);
+                await DocumentView.makeCustomViewClicked(target, undefined, Docs.Create.FreeformDocument);
                 media.push({ url, description });
             }
             if (media.length) {
diff --git a/src/client/util/ClientUtils.ts.temp b/src/client/util/ClientUtils.ts.temp
new file mode 100644
index 000000000..f9fad5ed9
--- /dev/null
+++ b/src/client/util/ClientUtils.ts.temp
@@ -0,0 +1,3 @@
+export namespace ClientUtils {
+    export const RELEASE = "mode";
+}
\ No newline at end of file
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index 937aff0d6..ac803d977 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -77,8 +77,13 @@ export class ContextMenu extends React.Component {
     @action
     clearItems() {
         this._items = [];
+        this._defaultPrefix = "";
+        this._defaultItem = undefined;
     }
 
+    _defaultPrefix: string = "";
+    _defaultItem: ((name: string) => void) | undefined;
+
     findByDescription = (target: string, toLowerCase = false) => {
         return this._items.find(menuItem => {
             let reference = menuItem.description;
@@ -93,6 +98,11 @@ export class ContextMenu extends React.Component {
             this._items.push(item);
         }
     }
+    @action
+    setDefaultItem(prefix: string, item: (name: string) => void) {
+        this._defaultPrefix = prefix;
+        this._defaultItem = item;
+    }
 
     getItems() {
         return this._items;
@@ -248,7 +258,11 @@ export class ContextMenu extends React.Component {
             e.preventDefault();
         } else if (e.key === "Enter" || e.key === "Tab") {
             const item = this.flatItems[this.selectedIndex];
-            item && item.event({ x: this.pageX, y: this.pageY });
+            if (item) {
+                item.event({ x: this.pageX, y: this.pageY });
+            } else if (this._searchString.startsWith(this._defaultPrefix)) {
+                this._defaultItem?.(this._searchString.substring(this._defaultPrefix.length));
+            }
             this.closeMenu();
             e.preventDefault();
         }
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index f2ae93b78..b01ca7a41 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -1,6 +1,5 @@
-import { action, observable } from "mobx";
+import { action, observable, runInAction, ObservableSet } from "mobx";
 import { observer } from "mobx-react";
-import { DragManager } from "../util/DragManager";
 import { SelectionManager } from "../util/SelectionManager";
 import { undoBatch } from "../util/UndoManager";
 import './TemplateMenu.scss';
@@ -9,8 +8,6 @@ import { Template, Templates } from "./Templates";
 import React = require("react");
 import { Doc } from "../../new_fields/Doc";
 import { StrCast } from "../../new_fields/Types";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faEdit, faChevronCircleUp } from "@fortawesome/free-solid-svg-icons";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -52,11 +49,8 @@ export interface TemplateMenuProps {
 export class TemplateMenu extends React.Component<TemplateMenuProps> {
     @observable private _hidden: boolean = true;
 
-    toggleCustom = (e: React.ChangeEvent<HTMLInputElement>): void => {
-        this.props.docs.map(dv => dv.setCustomView(e.target.checked));
-    }
-    toggleNarrative = (e: React.ChangeEvent<HTMLInputElement>): void => {
-        this.props.docs.map(dv => dv.setNarrativeView(e.target.checked));
+    toggleLayout = (e: React.ChangeEvent<HTMLInputElement>, layout: string): void => {
+        this.props.docs.map(dv => dv.setCustomView(e.target.checked, layout));
     }
 
     toggleFloat = (e: React.ChangeEvent<HTMLInputElement>): void => {
@@ -92,17 +86,34 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
         });
     }
 
+    // todo: add brushes to brushMap to save with a style name
+    onCustomKeypress = (e: React.KeyboardEvent) => {
+        if (e.key === "Enter") {
+            runInAction(() => TemplateMenu._addedKeys.add(this._customRef.current!.value));
+        }
+    }
+    componentDidMount() {
+        !TemplateMenu._addedKeys && (TemplateMenu._addedKeys = new ObservableSet(["narrative"]));
+        Array.from(Object.keys(Doc.GetProto(this.props.docs[0].props.Document))).
+            filter(key => key.startsWith("layout_")).
+            map(key => runInAction(() => TemplateMenu._addedKeys.add(key.replace("layout_", ""))));
+    }
+
+    static _addedKeys = new ObservableSet(["narrative"]);
+    _customRef = React.createRef<HTMLInputElement>();
     render() {
         const layout = Doc.Layout(this.props.docs[0].Document);
         const templateMenu: Array<JSX.Element> = [];
         this.props.templates.forEach((checked, template) =>
             templateMenu.push(<TemplateToggle key={template.Name} template={template} checked={checked} toggle={this.toggleTemplate} />));
         templateMenu.push(<OtherToggle key={"float"} name={"Float"} checked={this.props.docs[0].Document.z ? true : false} toggle={this.toggleFloat} />);
-        templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
-        templateMenu.push(<OtherToggle key={"narrative"} name={"Narrative"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") === "layout_narrative"} toggle={this.toggleNarrative} />);
         templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout._chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
+        TemplateMenu._addedKeys && Array.from(TemplateMenu._addedKeys).map(layout =>
+            templateMenu.push(<OtherToggle key={layout} name={layout} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") === "layout_" + layout} toggle={e => this.toggleLayout(e, layout)} />)
+        );
         return <ul className="template-list" style={{ display: "block" }}>
             {templateMenu}
+            <input placeholder="+ layout" ref={this._customRef} onKeyPress={this.onCustomKeypress}></input>
         </ul>;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index e1577cfee..843c743db 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -385,4 +385,4 @@
     .rc-switch-checked .rc-switch-inner {
         left: 8px;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 41247c1b3..91c7ca76e 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -389,6 +389,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
                     ref={this.createRef}
                     style={{
+                        overflowY: this.props.active() ? "auto" : "hidden",
                         transform: `scale(${Math.min(1, this.props.PanelHeight() / this.layoutDoc[HeightSym]())})`,
                         height: `${Math.max(100, 100 * 1 / Math.min(this.props.PanelWidth() / this.layoutDoc[WidthSym](), this.props.PanelHeight() / this.layoutDoc[HeightSym]()))}%`,
                         transformOrigin: "top"
@@ -396,7 +397,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
                     onDrop={this.onDrop.bind(this)}
                     onContextMenu={this.onContextMenu}
-                    onWheel={e => e.stopPropagation()} >
+                    onWheel={e => this.props.active() && e.stopPropagation()} >
                     {this.renderedSections}
                     {!this.showAddAGroup ? (null) :
                         <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 801cab896..2a9f903bb 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -4,7 +4,7 @@ import { faPalette } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc } from "../../../new_fields/Doc";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { NumCast, StrCast } from "../../../new_fields/Types";
@@ -282,6 +282,18 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                     }
                 }, icon: "compress-arrows-alt"
             }));
+        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => DocListCast(dataDoc[fieldKey]).length).map(fieldKey =>
+            docItems.push({
+                description: ":" + fieldKey, event: () => {
+                    const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
+                    if (created) {
+                        if (this.props.parent.Document.isTemplateDoc) {
+                            Doc.MakeMetadataFieldTemplate(created, this.props.parent.props.Document);
+                        }
+                        return this.props.parent.props.addDocument(created);
+                    }
+                }, icon: "compress-arrows-alt"
+            }));
         layoutItems.push({ description: ":freeform", event: () => this.props.parent.props.addDocument(Docs.Create.FreeformDocument([], { _width: 200, _height: 200, _LODdisable: true })), icon: "compress-arrows-alt" });
         layoutItems.push({ description: ":carousel", event: () => this.props.parent.props.addDocument(Docs.Create.CarouselDocument([], { _width: 400, _height: 200, _LODdisable: true })), icon: "compress-arrows-alt" });
         layoutItems.push({ description: ":columns", event: () => this.props.parent.props.addDocument(Docs.Create.MulticolumnDocument([], { _width: 200, _height: 200 })), icon: "compress-arrows-alt" });
@@ -289,6 +301,16 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
         ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
         ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" });
+        ContextMenu.Instance.setDefaultItem("::", (name: string): void => {
+            Doc.GetProto(this.props.parent.props.Document)[name] = "";
+            const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true });
+            if (created) {
+                if (this.props.parent.Document.isTemplateDoc) {
+                    Doc.MakeMetadataFieldTemplate(created, this.props.parent.props.Document);
+                }
+                this.props.parent.props.addDocument(created);
+            }
+        });
         const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
         ContextMenu.Instance.displayMenu(pt[0], pt[1]);
     }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 9e07b51d1..f75184b42 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -9,12 +9,12 @@ import { Id } from '../../../new_fields/FieldSymbols';
 import { listSpec } from "../../../new_fields/Schema";
 import { ScriptField } from '../../../new_fields/ScriptField';
 import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { ImageField } from '../../../new_fields/URLField';
+import { ImageField, PdfField, VideoField, AudioField } from '../../../new_fields/URLField';
 import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
 import { emptyFunction, returnTransparent, returnTrue, Utils, returnOne } from "../../../Utils";
 import { GooglePhotos } from '../../apis/google_docs/GooglePhotosClientUtils';
 import { DocServer } from "../../DocServer";
-import { Docs, DocUtils } from "../../documents/Documents";
+import { Docs, DocUtils, DocumentOptions } from "../../documents/Documents";
 import { DocumentType } from '../../documents/DocumentTypes';
 import { ClientUtils } from '../../util/ClientUtils';
 import { DocumentManager } from "../../util/DocumentManager";
@@ -49,6 +49,7 @@ import { RadialMenu } from './RadialMenu';
 import { RadialMenuProps } from './RadialMenuItem';
 
 import { CollectionStackingView } from '../collections/CollectionStackingView';
+import { RichTextField } from '../../../new_fields/RichTextField';
 
 library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
     fa.faSquare, fa.faConciergeBell, fa.faWindowRestore, fa.faFolder, fa.faMapPin, fa.faLink, fa.faFingerprint, fa.faCrosshairs, fa.faDesktop, fa.faUnlock, fa.faLock, fa.faLaptopCode, fa.faMale,
@@ -515,43 +516,45 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @undoBatch
     deleteClicked = (): void => { SelectionManager.DeselectAll(); this.props.removeDocument && this.props.removeDocument(this.props.Document); }
 
-    static makeNativeViewClicked = (doc: Doc) => {
-        undoBatch(() => doc.layoutKey = "layout")();
+    static makeNativeViewClicked = (doc: Doc, prevLayout: string) => {
+        undoBatch(() => {
+            if (StrCast(doc.title).endsWith("_" + prevLayout)) doc.title = StrCast(doc.title).replace("_" + prevLayout, "");
+            doc.layoutKey = "layout";
+        })();
     }
 
-    static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, name: string = "custom") => {
+    static makeCustomViewClicked = (doc: Doc, dataDoc: Opt<Doc>, creator: (documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc, name: string = "custom") => {
         const batch = UndoManager.StartBatch("CustomViewClicked");
-        const customName = "layout-" + name;
+        const customName = "layout_" + name;
+        if (!StrCast(doc.title).endsWith(name)) doc.title = doc.title + "_" + name;
         if (doc[customName] === undefined) {
             const _width = NumCast(doc._width);
             const _height = NumCast(doc._height);
             const options = { title: "data", _width, x: -_width / 2, y: - _height / 2, };
 
-            let fieldTemplate: Doc;
-            switch (doc.type) {
-                case DocumentType.TEXT:
-                    fieldTemplate = Docs.Create.TextDocument("", options);
-                    break;
-                case DocumentType.PDF:
-                    fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
-                    break;
-                case DocumentType.VID:
-                    fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
-                    break;
-                case DocumentType.AUDIO:
-                    fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
-                    break;
-                default:
-                    fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
+            const field = doc.data;
+            let fieldTemplate: Opt<Doc>;
+            if (field instanceof RichTextField || typeof (field) === "string") {
+                fieldTemplate = Docs.Create.TextDocument("", options);
+            } else if (field instanceof PdfField) {
+                fieldTemplate = Docs.Create.PdfDocument("http://www.msn.com", options);
+            } else if (field instanceof VideoField) {
+                fieldTemplate = Docs.Create.VideoDocument("http://www.cs.brown.edu", options);
+            } else if (field instanceof AudioField) {
+                fieldTemplate = Docs.Create.AudioDocument("http://www.cs.brown.edu", options);
+            } else if (field instanceof ImageField) {
+                fieldTemplate = Docs.Create.ImageDocument("http://www.cs.brown.edu", options);
             }
 
-            fieldTemplate.backgroundColor = doc.backgroundColor;
-            fieldTemplate.heading = 1;
-            fieldTemplate._autoHeight = true;
+            if (fieldTemplate) {
+                fieldTemplate.backgroundColor = doc.backgroundColor;
+                fieldTemplate.heading = 1;
+                fieldTemplate._autoHeight = true;
+            }
 
-            const docTemplate = Docs.Create.FreeformDocument([fieldTemplate], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
+            const docTemplate = creator(fieldTemplate ? [fieldTemplate] : [], { title: customName + "(" + doc.title + ")", isTemplateDoc: true, _width: _width + 20, _height: Math.max(100, _height + 45) });
 
-            Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate));
+            fieldTemplate && Doc.MakeMetadataFieldTemplate(fieldTemplate, Doc.GetProto(docTemplate));
             Doc.ApplyTemplateTo(docTemplate, dataDoc || doc, customName, undefined);
         } else {
             doc.layoutKey = customName;
@@ -642,29 +645,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
     }
 
-    @undoBatch
-    @action
-    setNarrativeView = (custom: boolean): void => {
-        if (custom) {
-            custom ? DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, "narrative") : DocumentView.makeNativeViewClicked(this.props.Document);
-            //     this.props.Document.layout_narrative = CollectionView.LayoutString("narrative");
-            //     this.props.Document.layoutKey = "layout_narrative";
-            //     this.props.Document._nativeWidth = this.props.Document._nativeHeight = undefined;
-            //     !this.props.Document.narrative && (Doc.GetProto(this.props.Document).narrative = new List<Doc>([]));
-            //     this.props.Document._viewType = CollectionViewType.Stacking;
-            // } else {
-            //     DocumentView.makeNativeViewClicked(this.props.Document);
-        }
-    }
-
     @undoBatch
     @action
     setCustomView =
-        (custom: boolean): void => {
+        (custom: boolean, layout: string): void => {
             if (this.props.ContainingCollectionView?.props.DataDoc || this.props.ContainingCollectionView?.props.Document.isTemplateDoc) {
                 Doc.MakeMetadataFieldTemplate(this.props.Document, this.props.ContainingCollectionView.props.Document);
+            } else if (custom) {
+                DocumentView.makeNativeViewClicked(this.props.Document, StrCast(this.props.Document.layoutKey).split("_")[1]);
+                DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc, Docs.Create.StackingDocument, layout);
             } else {
-                custom ? DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc) : DocumentView.makeNativeViewClicked(this.props.Document);
+                DocumentView.makeNativeViewClicked(this.props.Document, StrCast(this.props.Document.layoutKey).split("_")[1]);
             }
         }
 
@@ -744,11 +735,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         layoutItems.push({ description: this.Document.lockedTransform ? "Unlock Transform" : "Lock Transform", event: this.toggleLockTransform, icon: BoolCast(this.Document.lockedTransform) ? "unlock" : "lock" });
         layoutItems.push({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
         layoutItems.push({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" });
-        if (this.Document.type !== DocumentType.COL && this.Document.type !== DocumentType.TEMPLATE) {
-            layoutItems.push({ description: "Use Custom Layout", event: () => DocumentView.makeCustomViewClicked(this.props.Document, this.props.DataDoc), icon: "concierge-bell" });
-        } else {
-            layoutItems.push({ description: "Use Native Layout", event: () => DocumentView.makeNativeViewClicked(this.props.Document), icon: "concierge-bell" });
-        }
         !existing && cm.addItem({ description: "Layout...", subitems: layoutItems, icon: "compass" });
 
         const more = ContextMenu.Instance.findByDescription("More...");
diff --git a/src/new_fields/RichTextUtils.ts b/src/new_fields/RichTextUtils.ts
index 6f34c82db..c50f8cc48 100644
--- a/src/new_fields/RichTextUtils.ts
+++ b/src/new_fields/RichTextUtils.ts
@@ -274,7 +274,7 @@ export namespace RichTextUtils {
             const backingDocId = StrCast(textNote[guid]);
             if (!backingDocId) {
                 const backingDoc = Docs.Create.ImageDocument(src, { _width: 300, _height: 300 });
-                DocumentView.makeCustomViewClicked(backingDoc, undefined);
+                DocumentView.makeCustomViewClicked(backingDoc, undefined, Docs.Create.FreeformDocument);
                 docid = backingDoc[Id];
                 textNote[guid] = docid;
             } else {
@@ -403,7 +403,7 @@ export namespace RichTextUtils {
                                     let exported = (await Cast(linkDoc.anchor2, Doc))!;
                                     if (!exported.customLayout) {
                                         exported = Doc.MakeAlias(exported);
-                                        DocumentView.makeCustomViewClicked(exported, undefined);
+                                        DocumentView.makeCustomViewClicked(exported, undefined, Docs.Create.FreeformDocument);
                                         linkDoc.anchor2 = exported;
                                     }
                                     url = Utils.shareUrl(exported[Id]);
-- 
cgit v1.2.3-70-g09d2

