From 0fc47fefcb72592bd34e238949db9e98a84b8a63 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Mon, 5 Jun 2023 19:42:06 -0400
Subject: topbar, buttons etc

---
 src/client/views/topbar/TopBar.tsx | 1 +
 1 file changed, 1 insertion(+)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 9bd2ba5ce..32b56b202 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -86,6 +86,7 @@ export class TopBar extends React.Component {
                     tooltip="Browsing mode for directly navigating to documents"
                     size={Size.SMALL}
                     color={'white'}
+                    style={{fontWeight: 700, fontSize: '1rem'}}
                     onClick={(e: React.MouseEvent) => {
                         const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
                         ContextMenu.Instance.addItem({ description: 'Open Dashboard View', event: this.navigateToHome, icon: 'edit' });
-- 
cgit v1.2.3-70-g09d2


From cb4fbf58fb30b3ea863f5107674dd366566e39a7 Mon Sep 17 00:00:00 2001
From: geireann <geireann.lindfield@gmail.com>
Date: Tue, 6 Jun 2023 17:04:01 -0400
Subject: updated share button on topbar

---
 package-lock.json                  |  6 +++---
 package.json                       |  2 +-
 src/client/views/topbar/TopBar.tsx | 17 +++++++++--------
 3 files changed, 13 insertions(+), 12 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/package-lock.json b/package-lock.json
index 052a9fa14..50b0ae024 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4497,9 +4497,9 @@
             }
         },
         "browndash-components": {
-            "version": "0.0.33",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.33.tgz",
-            "integrity": "sha512-GvapLe8z61FLVru7rosxTT9mgqbhci2frAXkp7xzzgq6KubQZK56oNUygsq5Vk9SKRYdf82ovazI/MOXLcXV7A==",
+            "version": "0.0.34",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.34.tgz",
+            "integrity": "sha512-wlvNL41FWSvkhDtWWOd6mPZcT+qS6R0eLJ2IrFMk0WG9ejEoURVy8URy566ZLCUKQkkZ3VKISVeidX/pdSRmAg==",
             "requires": {
                 "color": "^4.2.3",
                 "react-color": "^2.19.3",
diff --git a/package.json b/package.json
index 965439600..f8392171f 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.33",
+        "browndash-components": "0.0.34",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 32b56b202..b591e0250 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, IconButton, Size } from 'browndash-components';
+import { Button, IconButton, Size, Type } from 'browndash-components';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -102,13 +102,6 @@ export class TopBar extends React.Component {
                         dashView?.showContextMenu(e.clientX + 20, e.clientY + 30);
                     }}
                 />
-                <Button
-                    text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
-                    onClick={() => {
-                        SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
-                    }}
-                    size={Size.SMALL}
-                />
                 {!Doc.noviceMode && (
                     <IconButton
                         tooltip="Work on a copy of the dashboard layout"
@@ -134,6 +127,14 @@ export class TopBar extends React.Component {
     @computed get topbarRight() {
         return (
             <div className="topbar-right">
+                {Doc.ActiveDashboard && <Button
+                    text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
+                    type={Type.TERT}
+                    onClick={() => {
+                        SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
+                    }}
+                    size={Size.SMALL}
+                />}
                 <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
                 <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                 <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
-- 
cgit v1.2.3-70-g09d2


From a217c9261990cb751119ae68e7dcc7e32f48e529 Mon Sep 17 00:00:00 2001
From: srichman333 <sarah_n_richman@brown.edu>
Date: Fri, 16 Jun 2023 11:13:52 -0400
Subject: cleaner w/ effectiveAcls

---
 src/client/util/SharingManager.tsx       | 19 ++++++-------------
 src/client/views/DocComponent.tsx        | 14 +++++++++-----
 src/client/views/DocumentDecorations.tsx |  5 ++---
 src/client/views/PropertiesView.tsx      |  1 -
 src/client/views/topbar/TopBar.tsx       |  2 +-
 src/fields/util.ts                       | 32 ++++++++++++++------------------
 6 files changed, 32 insertions(+), 41 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 6cbc060fa..a161b4dc2 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -80,7 +80,7 @@ export class SharingManager extends React.Component<{}> {
     @observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component)
     private populating: boolean = false; // whether the list of users is populating or not
     @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
-    @observable private overridePrivate: boolean = false; // whether child docs in a collection/dashboard should be changed to be less private
+    @observable private overridePrevious: boolean = false; // whether child docs in a collection/dashboard should be changed to be less private
     @observable private myDocAcls: boolean = false; // whether the My Docs checkbox is selected or not
 
     // private get linkVisible() {
@@ -160,10 +160,10 @@ export class SharingManager extends React.Component<{}> {
         const isDashboard = DocListCast(Doc.MyDashboards.data).indexOf(target) !== -1;
 
         // setting the same acl for a docs within the doc being shared if they haven't been set yet
-        // or if the 'Override Private' checkbox is selected
+        // or if the 'Override previous' checkbox is selected
         var childDocs = DocListCast(target.data);
         childDocs.map(doc => {
-            if (this.overridePrivate || doc[acl]==undefined){
+            if (this.overridePrevious || doc[acl]==undefined){
                 this.setInternalSharing(recipient, permission, doc);
             }
         });
@@ -204,7 +204,7 @@ export class SharingManager extends React.Component<{}> {
         // or if the 'Override Private' checkbox is selected
         var childDocs = DocListCast(target.data);
         childDocs.map(doc => {
-            if (this.overridePrivate || doc[acl]==undefined){
+            if (this.overridePrevious || doc[acl]==undefined){
                 this.setInternalGroupSharing(group, permission, doc);
             }
         });
@@ -279,7 +279,7 @@ export class SharingManager extends React.Component<{}> {
             const dashboards = DocListCast(Doc.MyDashboards.data);
             docs.forEach(doc => {
                 const isDashboard = dashboards.indexOf(doc) !== -1;
-                if (this.overridePrivate) this.shareFromPropertiesSidebar(shareWith, permission, DocListCast(doc.data));
+                if (this.overridePrevious) this.shareFromPropertiesSidebar(shareWith, permission, DocListCast(doc.data));
                 if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc, undefined, undefined, isDashboard);
                 this.setDashboardBackground(doc, permission as SharingPermissions);
             });
@@ -520,13 +520,6 @@ export class SharingManager extends React.Component<{}> {
             // .filter(({ user }) => (docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(user.email)}`) : docs[0]?.author !== user.email))
             .filter(({ user }) => docs[0]?.author !== user.email)
             .map(({ user, linkDatabase, sharingDoc, userColor }) => {
-                const dashboardList = SelectionManager.Views().length < 2 ? [targetDoc] : SelectionManager.Views().map(docView => docView.props.Document);
-                // const dashboard = dashboardList[0]
-                const dashboard = Doc.ActiveDashboard;
-                var docToUse = dashboard;
-
-                docToUse = Doc.GetProto(this.targetDoc!);
-
                 const userKey = `acl-${normalizeEmail(user.email)}`;
                 const uniform = docs.map(doc => (this.layoutDocAcls ? doc : doc[DocData])).every(doc => doc?.[DocAcl]?.[userKey] === docs[0]?.[DocAcl]?.[userKey]);
                 const permissions = uniform ? StrCast(targetDoc?.[userKey]) : '-multiple-';
@@ -647,7 +640,7 @@ export class SharingManager extends React.Component<{}> {
                             <div className="acl-container">
                                 {Doc.noviceMode ? null : (
                                     <div className="layoutDoc-acls">
-                                        <input type="checkbox" onChange={action(() => (this.overridePrivate = !this.overridePrivate))} checked={this.overridePrivate} /> <label>Override Private </label>
+                                        <input type="checkbox" onChange={action(() => (this.overridePrevious = !this.overridePrevious))} checked={this.overridePrevious} /> <label>Override previous </label>
                                         <input type="checkbox" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} /> <label>Layout</label>
                                     </div>
                                 )}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index db24229dc..7e8946ca0 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -1,9 +1,9 @@
 import { action, computed, observable } from 'mobx';
 import { DateField } from '../../fields/DateField';
-import { DocListCast, Opt, Doc } from '../../fields/Doc';
+import { DocListCast, Opt, Doc, ReverseHierarchyMap, HierarchyMapping } from '../../fields/Doc';
 import { AclAdmin, AclAugment, AclEdit, AclPrivate, AclReadonly, DocAcl, DocData } from '../../fields/DocSymbols';
 import { List } from '../../fields/List';
-import { Cast, ScriptCast } from '../../fields/Types';
+import { Cast, ScriptCast, StrCast } from '../../fields/Types';
 import { denormalizeEmail, distributeAcls, GetEffectiveAcl, inheritParentAcls, SharingPermissions } from '../../fields/util';
 import { returnFalse } from '../../Utils';
 import { DocUtils } from '../documents/Documents';
@@ -191,11 +191,15 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps>()
             }
             const added = docs;
             if (added.length) {
-                const aclKeys = Object.keys(this.props.Document[DocAcl] ?? {});
+                const aclKeys = Object.keys(Doc.GetProto(this.props.Document)[DocAcl] ?? {});
+
                 aclKeys.forEach(key =>
                     added.forEach(d => {
-                        if (d.author === denormalizeEmail(key.substring(4)) && !d.createdFrom) {
-                            distributeAcls(key, SharingPermissions.Admin, d);
+                        if (key != 'acl-Me'){
+                            const permissionString = StrCast(Doc.GetProto(this.props.Document)[key])
+                            const permissionSymbol = ReverseHierarchyMap.get(permissionString)!.acl
+                            const permission = HierarchyMapping.get(permissionSymbol)!.name
+                            distributeAcls(key, permission, d)
                         }
                     })
                 );
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index ff98e18d4..8e224a4b6 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -7,7 +7,7 @@ import { observer } from 'mobx-react';
 import { FaUndo } from 'react-icons/fa';
 import { Utils, aggregateBounds, emptyFunction, numberValue, returnFalse, setupMoveUpEvents } from '../../Utils';
 import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field } from '../../fields/Doc';
+import { Doc, DocListCast, Field, HierarchyMapping } from '../../fields/Doc';
 import { AclAdmin, AclAugment, AclEdit, DocData, Height, Width } from '../../fields/DocSymbols';
 import { InkField } from '../../fields/InkField';
 import { RichTextField } from '../../fields/RichTextField';
@@ -765,8 +765,7 @@ const dragDocView = SelectionManager.Views()[0];
         }
 
         // sharing
-        // const docShareMode = Doc.GetProto(seldocview.rootDoc)['acl-Public'];
-        const docShareMode = Doc.GetProto(seldocview.rootDoc)['acl-' + normalizeEmail(Doc.CurrentUserEmail)];
+        const docShareMode = HierarchyMapping.get(GetEffectiveAcl(seldocview.rootDoc))!.name
         const shareMode = StrCast(docShareMode);
         var shareSymbolIcon = null;
         switch (shareMode) {
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 4674bc0f4..8648d84c2 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -499,7 +499,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 const groupKey = 'acl-' + normalizeEmail(StrCast(group.title));
                 if (Doc.ActiveDashboard[groupKey] != '' && Doc.ActiveDashboard[groupKey] != undefined) {
                     const permission = StrCast(target[groupKey]);
-                    console.log(permission)
                     tableEntries.unshift(this.sharingItem(StrCast(group.title), showAdmin, permission, false));
                 }
             }
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 71daad1a9..834156295 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -103,7 +103,7 @@ export class TopBar extends React.Component {
                     }}
                 />
                 <Button
-                    text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
+                    text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'}
                     onClick={() => {
                         SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                     }}
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 469e4d944..6c8758875 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -17,6 +17,7 @@ import { RefField } from './RefField';
 import { SchemaHeaderField } from './SchemaHeaderField';
 import { ComputedField } from './ScriptField';
 import { ScriptCast, StrCast } from './Types';
+import { GroupManager } from '../client/util/GroupManager';
 
 function _readOnlySetter(): never {
     throw new Error("Documents can't be modified in read-only mode");
@@ -171,7 +172,15 @@ const getEffectiveAclCache = computedFn(function (target: any, user?: string) {
  * Calculates the effective access right to a document for the current user.
  */
 export function GetEffectiveAcl(target: any, user?: string): symbol {
-    target = Doc.GetProto(target);
+    if (!target) return AclPrivate;
+    if (target[UpdatingFromServer]) return AclAdmin;
+    return getEffectiveAclCache(Doc.GetProto(target), user); // all changes received from the server must be processed as Admin.  return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
+}
+
+/**
+ * Calculates the effective access layout right to a document for the current user.
+ */
+export function GetEffectiveLayoutAcl(target: any, user?: string): symbol {
     if (!target) return AclPrivate;
     if (target[UpdatingFromServer]) return AclAdmin;
     return getEffectiveAclCache(target, user); // all changes received from the server must be processed as Admin.  return this directly so that the acls aren't cached (UpdatingFromServer is not observable)
@@ -195,7 +204,6 @@ export function SetCachedGroups(groups: string[]) {
 }
 function getEffectiveAcl(target: any, user?: string): symbol {
     const targetAcls = target[DocAcl];
-    console.log(target.title, targetAcls)
     if (targetAcls?.['acl-Me'] === AclAdmin || GetCachedGroupByName('Admin')) return AclAdmin;
 
     const userChecked = user || Doc.CurrentUserEmail; // if the current user is the author of the document / the current user is a member of the admin group
@@ -205,31 +213,20 @@ function getEffectiveAcl(target: any, user?: string): symbol {
             // there are issues with storing fields with . in the name, so they are replaced with _ during creation
             // as a result we need to restore them again during this comparison.
             const entity = denormalizeEmail(key.substring(4)); // an individual or a group
-            if (HierarchyMapping.get(value as symbol)!.level > HierarchyMapping.get(effectiveAcl)!.level) {
-                if (GetCachedGroupByName(entity) || userChecked === entity || entity === 'Me') {
+            if (GetCachedGroupByName(entity) || userChecked === entity || entity === 'Me') {
+                if (HierarchyMapping.get(value as symbol)!.level > HierarchyMapping.get(effectiveAcl)!.level) {
                     effectiveAcl = value as symbol;
                 }
             }
+            console.log(targetAcls)
         }
 
-        // if there's an overriding acl set through the properties panel or sharing menu, that's what's returned if the user isn't an admin of the document
-        //const override = targetAcls['acl-Override'];
-        // if (override !== AclUnset && override !== undefined) effectiveAcl = override;
-
         return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)!.level < aclLevel.editable ? AclEdit : effectiveAcl;
     }
     // authored documents are private until an ACL is set.
     const targetAuthor = target.__fieldTuples?.author || target.author; // target may be a Doc of Proxy, so check __fieldTuples.author and .author
     if (targetAuthor && targetAuthor !== userChecked) return AclPrivate;
     return AclAdmin;
-    let acl = AclPrivate;
-    if (user) {
-        acl = target['acl-' + user];
-    } else {
-        acl = target['acl-' + normalizeEmail(Doc.CurrentUserEmail)];
-    }
-    console.log(target['acl-' + normalizeEmail(Doc.CurrentUserEmail)]);
-    return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(acl)!.level < aclLevel.editable ? AclEdit : acl;
 }
 /**
  * Recursively distributes the access right for a user across the children of a document and its annotations.
@@ -240,11 +237,10 @@ function getEffectiveAcl(target: any, user?: string): symbol {
  * inheritingFromCollection is not currently being used but could be used if acl assignment defaults change
  */
 export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[], isDashboard?: boolean) {
+    console.log(key,acl,target.title)
     if (!visited) visited = [] as Doc[];
     if (!target || visited.includes(target)) return;
-
     if ((target._type_collection === CollectionViewType.Docking && visited.length > 1) || Doc.GetProto(visited[0]) !== Doc.GetProto(target)) {
-        target[key] = acl;
         Doc.GetProto(target)[key] = acl;
         if (target !== Doc.GetProto(target)) {
             //apparently we can't call updateCachedAcls twice (once for the main dashboard, and again for the nested dashboard...???)
-- 
cgit v1.2.3-70-g09d2


From 9b52c0798508a003a722c7bcd849c7ed977e3487 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Sun, 9 Jul 2023 16:16:34 -0400
Subject: updated to add tooltips

also removed background colour for stacking docs (ask bob why we are setting arbitrary background colour for stacking docs?)
---
 package-lock.json                                  | 2635 ++++++++++++++++++--
 package.json                                       |    2 +-
 .../views/collections/CollectionStackingView.tsx   |    2 +-
 src/client/views/nodes/button/FontIconBox.tsx      |    2 +-
 src/client/views/topbar/TopBar.scss                |   18 +-
 src/client/views/topbar/TopBar.tsx                 |   26 +-
 .../Session/utilities/session_config.ts            |    2 +-
 src/server/server_Initialization.ts                |    2 +-
 8 files changed, 2496 insertions(+), 193 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/package-lock.json b/package-lock.json
index b1cb63540..c48c57357 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,21 +4,83 @@
     "lockfileVersion": 1,
     "requires": true,
     "dependencies": {
-        "@babel/code-frame": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
-            "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+        "@ampproject/remapping": {
+            "version": "2.2.1",
+            "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+            "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
             "requires": {
-                "@babel/highlight": "^7.18.6"
+                "@jridgewell/gen-mapping": "^0.3.0",
+                "@jridgewell/trace-mapping": "^0.3.9"
+            }
+        },
+        "@babel/code-frame": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
+            "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+            "requires": {
+                "@babel/highlight": "^7.22.5"
+            }
+        },
+        "@babel/compat-data": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
+            "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg=="
+        },
+        "@babel/core": {
+            "version": "7.22.8",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz",
+            "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==",
+            "requires": {
+                "@ampproject/remapping": "^2.2.0",
+                "@babel/code-frame": "^7.22.5",
+                "@babel/generator": "^7.22.7",
+                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/helpers": "^7.22.6",
+                "@babel/parser": "^7.22.7",
+                "@babel/template": "^7.22.5",
+                "@babel/traverse": "^7.22.8",
+                "@babel/types": "^7.22.5",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3",
+                "convert-source-map": "^1.7.0",
+                "debug": "^4.1.0",
+                "gensync": "^1.0.0-beta.2",
+                "json5": "^2.2.2"
+            },
+            "dependencies": {
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                },
+                "debug": {
+                    "version": "4.3.4",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+                    "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+                    "requires": {
+                        "ms": "2.1.2"
+                    }
+                },
+                "json5": {
+                    "version": "2.2.3",
+                    "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+                    "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
+                },
+                "ms": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+                    "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+                }
             }
         },
         "@babel/generator": {
-            "version": "7.20.14",
-            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz",
-            "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==",
+            "version": "7.22.7",
+            "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz",
+            "integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==",
             "requires": {
-                "@babel/types": "^7.20.7",
+                "@babel/types": "^7.22.5",
                 "@jridgewell/gen-mapping": "^0.3.2",
+                "@jridgewell/trace-mapping": "^0.3.17",
                 "jsesc": "^2.5.1"
             }
         },
@@ -30,82 +92,1637 @@
                 "@babel/types": "^7.18.6"
             }
         },
+        "@babel/helper-builder-binary-assignment-operator-visitor": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.5.tgz",
+            "integrity": "sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-compilation-targets": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz",
+            "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==",
+            "requires": {
+                "@babel/compat-data": "^7.22.6",
+                "@babel/helper-validator-option": "^7.22.5",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3",
+                "browserslist": "^4.21.9",
+                "lru-cache": "^5.1.1"
+            },
+            "dependencies": {
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                },
+                "lru-cache": {
+                    "version": "5.1.1",
+                    "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+                    "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+                    "requires": {
+                        "yallist": "^3.0.2"
+                    }
+                },
+                "yallist": {
+                    "version": "3.1.1",
+                    "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+                    "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+                }
+            }
+        },
+        "@babel/helper-create-class-features-plugin": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz",
+            "integrity": "sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-function-name": "^7.22.5",
+                "@babel/helper-member-expression-to-functions": "^7.22.5",
+                "@babel/helper-optimise-call-expression": "^7.22.5",
+                "@babel/helper-replace-supers": "^7.22.5",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+                "@babel/helper-split-export-declaration": "^7.22.6",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                }
+            }
+        },
+        "@babel/helper-create-regexp-features-plugin": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz",
+            "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3",
+                "regexpu-core": "^5.3.1"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                }
+            }
+        },
+        "@babel/helper-define-polyfill-provider": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz",
+            "integrity": "sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A==",
+            "requires": {
+                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "debug": "^4.1.1",
+                "lodash.debounce": "^4.0.8",
+                "resolve": "^1.14.2"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                },
+                "debug": {
+                    "version": "4.3.4",
+                    "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+                    "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+                    "requires": {
+                        "ms": "2.1.2"
+                    }
+                },
+                "lodash.debounce": {
+                    "version": "4.0.8",
+                    "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+                    "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+                },
+                "ms": {
+                    "version": "2.1.2",
+                    "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+                    "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+                }
+            }
+        },
         "@babel/helper-environment-visitor": {
-            "version": "7.18.9",
-            "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
-            "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg=="
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
+            "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q=="
         },
         "@babel/helper-function-name": {
-            "version": "7.19.0",
-            "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
-            "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
+            "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+            "requires": {
+                "@babel/template": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-hoist-variables": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+            "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-member-expression-to-functions": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.22.5.tgz",
+            "integrity": "sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-module-imports": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
+            "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-module-transforms": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz",
+            "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==",
+            "requires": {
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-module-imports": "^7.22.5",
+                "@babel/helper-simple-access": "^7.22.5",
+                "@babel/helper-split-export-declaration": "^7.22.5",
+                "@babel/helper-validator-identifier": "^7.22.5",
+                "@babel/template": "^7.22.5",
+                "@babel/traverse": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-optimise-call-expression": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz",
+            "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-plugin-utils": {
+            "version": "7.20.2",
+            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+            "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
+        },
+        "@babel/helper-remap-async-to-generator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz",
+            "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-wrap-function": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                }
+            }
+        },
+        "@babel/helper-replace-supers": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz",
+            "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==",
+            "requires": {
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-member-expression-to-functions": "^7.22.5",
+                "@babel/helper-optimise-call-expression": "^7.22.5",
+                "@babel/template": "^7.22.5",
+                "@babel/traverse": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-simple-access": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+            "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-skip-transparent-expression-wrappers": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz",
+            "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==",
             "requires": {
-                "@babel/template": "^7.18.10",
-                "@babel/types": "^7.19.0"
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-split-export-declaration": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+            "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+            "requires": {
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helper-string-parser": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+            "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw=="
+        },
+        "@babel/helper-validator-identifier": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
+            "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ=="
+        },
+        "@babel/helper-validator-option": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz",
+            "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw=="
+        },
+        "@babel/helper-wrap-function": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz",
+            "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==",
+            "requires": {
+                "@babel/helper-function-name": "^7.22.5",
+                "@babel/template": "^7.22.5",
+                "@babel/traverse": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/helpers": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz",
+            "integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==",
+            "requires": {
+                "@babel/template": "^7.22.5",
+                "@babel/traverse": "^7.22.6",
+                "@babel/types": "^7.22.5"
+            }
+        },
+        "@babel/highlight": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz",
+            "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+            "requires": {
+                "@babel/helper-validator-identifier": "^7.22.5",
+                "chalk": "^2.0.0",
+                "js-tokens": "^4.0.0"
+            }
+        },
+        "@babel/parser": {
+            "version": "7.22.7",
+            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
+            "integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q=="
+        },
+        "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.5.tgz",
+            "integrity": "sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.5.tgz",
+            "integrity": "sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+                "@babel/plugin-transform-optional-chaining": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-external-helpers": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.22.5.tgz",
+            "integrity": "sha512-ngnNEWxmykPk82mH4ajZT0qTztr3Je6hrMuKAslZVM8G1YZTENJSYwrIGtt6KOtznug3exmAtF4so/nPqJuA4A==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-proposal-class-properties": {
+            "version": "7.18.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz",
+            "integrity": "sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==",
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.18.6",
+                "@babel/helper-plugin-utils": "^7.18.6"
+            }
+        },
+        "@babel/plugin-proposal-object-rest-spread": {
+            "version": "7.20.7",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz",
+            "integrity": "sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==",
+            "requires": {
+                "@babel/compat-data": "^7.20.5",
+                "@babel/helper-compilation-targets": "^7.20.7",
+                "@babel/helper-plugin-utils": "^7.20.2",
+                "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+                "@babel/plugin-transform-parameters": "^7.20.7"
+            }
+        },
+        "@babel/plugin-proposal-private-property-in-object": {
+            "version": "7.21.0-placeholder-for-preset-env.2",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz",
+            "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w=="
+        },
+        "@babel/plugin-proposal-unicode-property-regex": {
+            "version": "7.18.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz",
+            "integrity": "sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==",
+            "requires": {
+                "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+                "@babel/helper-plugin-utils": "^7.18.6"
+            }
+        },
+        "@babel/plugin-syntax-async-generators": {
+            "version": "7.8.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+            "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-class-properties": {
+            "version": "7.12.13",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+            "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.12.13"
+            }
+        },
+        "@babel/plugin-syntax-class-static-block": {
+            "version": "7.14.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+            "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.14.5"
+            }
+        },
+        "@babel/plugin-syntax-dynamic-import": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+            "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-export-namespace-from": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+            "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.3"
+            }
+        },
+        "@babel/plugin-syntax-import-assertions": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz",
+            "integrity": "sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-syntax-import-attributes": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz",
+            "integrity": "sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-syntax-import-meta": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+            "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4"
+            }
+        },
+        "@babel/plugin-syntax-json-strings": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+            "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-jsx": {
+            "version": "7.18.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+            "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.18.6"
+            }
+        },
+        "@babel/plugin-syntax-logical-assignment-operators": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+            "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4"
+            }
+        },
+        "@babel/plugin-syntax-nullish-coalescing-operator": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+            "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-numeric-separator": {
+            "version": "7.10.4",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+            "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.10.4"
+            }
+        },
+        "@babel/plugin-syntax-object-rest-spread": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+            "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-optional-catch-binding": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+            "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-optional-chaining": {
+            "version": "7.8.3",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+            "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.8.0"
+            }
+        },
+        "@babel/plugin-syntax-private-property-in-object": {
+            "version": "7.14.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+            "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.14.5"
+            }
+        },
+        "@babel/plugin-syntax-top-level-await": {
+            "version": "7.14.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+            "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.14.5"
+            }
+        },
+        "@babel/plugin-syntax-typescript": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz",
+            "integrity": "sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-syntax-unicode-sets-regex": {
+            "version": "7.18.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz",
+            "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==",
+            "requires": {
+                "@babel/helper-create-regexp-features-plugin": "^7.18.6",
+                "@babel/helper-plugin-utils": "^7.18.6"
+            }
+        },
+        "@babel/plugin-transform-arrow-functions": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz",
+            "integrity": "sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-async-generator-functions": {
+            "version": "7.22.7",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz",
+            "integrity": "sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg==",
+            "requires": {
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-remap-async-to-generator": "^7.22.5",
+                "@babel/plugin-syntax-async-generators": "^7.8.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-async-to-generator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz",
+            "integrity": "sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==",
+            "requires": {
+                "@babel/helper-module-imports": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-remap-async-to-generator": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-block-scoped-functions": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz",
+            "integrity": "sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-block-scoping": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.5.tgz",
+            "integrity": "sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-class-properties": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz",
+            "integrity": "sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==",
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-class-static-block": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.5.tgz",
+            "integrity": "sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==",
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-class-static-block": "^7.14.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-classes": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz",
+            "integrity": "sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-function-name": "^7.22.5",
+                "@babel/helper-optimise-call-expression": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-replace-supers": "^7.22.5",
+                "@babel/helper-split-export-declaration": "^7.22.6",
+                "globals": "^11.1.0"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-computed-properties": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz",
+            "integrity": "sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/template": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-destructuring": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.22.5.tgz",
+            "integrity": "sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-dotall-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz",
+            "integrity": "sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==",
+            "requires": {
+                "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-duplicate-keys": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz",
+            "integrity": "sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-dynamic-import": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.5.tgz",
+            "integrity": "sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-dynamic-import": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-exponentiation-operator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz",
+            "integrity": "sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==",
+            "requires": {
+                "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-export-namespace-from": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.5.tgz",
+            "integrity": "sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-for-of": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.5.tgz",
+            "integrity": "sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-function-name": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz",
+            "integrity": "sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==",
+            "requires": {
+                "@babel/helper-compilation-targets": "^7.22.5",
+                "@babel/helper-function-name": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-json-strings": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.5.tgz",
+            "integrity": "sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-json-strings": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-literals": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz",
+            "integrity": "sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-logical-assignment-operators": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.5.tgz",
+            "integrity": "sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-member-expression-literals": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz",
+            "integrity": "sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-modules-amd": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.22.5.tgz",
+            "integrity": "sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==",
+            "requires": {
+                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-modules-commonjs": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.22.5.tgz",
+            "integrity": "sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==",
+            "requires": {
+                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-simple-access": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-modules-systemjs": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.22.5.tgz",
+            "integrity": "sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==",
+            "requires": {
+                "@babel/helper-hoist-variables": "^7.22.5",
+                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-validator-identifier": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-modules-umd": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz",
+            "integrity": "sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==",
+            "requires": {
+                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-named-capturing-groups-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz",
+            "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==",
+            "requires": {
+                "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-new-target": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz",
+            "integrity": "sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-nullish-coalescing-operator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.5.tgz",
+            "integrity": "sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-numeric-separator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.5.tgz",
+            "integrity": "sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-object-rest-spread": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.5.tgz",
+            "integrity": "sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==",
+            "requires": {
+                "@babel/compat-data": "^7.22.5",
+                "@babel/helper-compilation-targets": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+                "@babel/plugin-transform-parameters": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-object-super": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz",
+            "integrity": "sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-replace-supers": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-optional-catch-binding": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.5.tgz",
+            "integrity": "sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-optional-catch-binding": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-optional-chaining": {
+            "version": "7.22.6",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz",
+            "integrity": "sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
+                "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-parameters": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.5.tgz",
+            "integrity": "sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-private-methods": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz",
+            "integrity": "sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==",
+            "requires": {
+                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-private-property-in-object": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.5.tgz",
+            "integrity": "sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-private-property-in-object": "^7.14.5"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-property-literals": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz",
+            "integrity": "sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-react-display-name": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz",
+            "integrity": "sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-react-jsx": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz",
+            "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-module-imports": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-jsx": "^7.22.5",
+                "@babel/types": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                },
+                "@babel/plugin-syntax-jsx": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
+                    "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.22.5"
+                    }
+                }
+            }
+        },
+        "@babel/plugin-transform-react-jsx-development": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
+            "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+            "requires": {
+                "@babel/plugin-transform-react-jsx": "^7.22.5"
+            }
+        },
+        "@babel/plugin-transform-react-pure-annotations": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz",
+            "integrity": "sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-regenerator": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.5.tgz",
+            "integrity": "sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "regenerator-transform": "^0.15.1"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-reserved-words": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz",
+            "integrity": "sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-shorthand-properties": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz",
+            "integrity": "sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-spread": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz",
+            "integrity": "sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-sticky-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz",
+            "integrity": "sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-template-literals": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz",
+            "integrity": "sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-typeof-symbol": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz",
+            "integrity": "sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-typescript": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz",
+            "integrity": "sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==",
+            "requires": {
+                "@babel/helper-annotate-as-pure": "^7.22.5",
+                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/plugin-syntax-typescript": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-annotate-as-pure": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+                    "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+                    "requires": {
+                        "@babel/types": "^7.22.5"
+                    }
+                },
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
             }
         },
-        "@babel/helper-hoist-variables": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
-            "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+        "@babel/plugin-transform-unicode-escapes": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.5.tgz",
+            "integrity": "sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==",
             "requires": {
-                "@babel/types": "^7.18.6"
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
             }
         },
-        "@babel/helper-module-imports": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
-            "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+        "@babel/plugin-transform-unicode-property-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz",
+            "integrity": "sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==",
             "requires": {
-                "@babel/types": "^7.18.6"
+                "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
             }
         },
-        "@babel/helper-plugin-utils": {
-            "version": "7.20.2",
-            "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
-            "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
-        },
-        "@babel/helper-split-export-declaration": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
-            "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+        "@babel/plugin-transform-unicode-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz",
+            "integrity": "sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==",
             "requires": {
-                "@babel/types": "^7.18.6"
+                "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/plugin-transform-unicode-sets-regex": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz",
+            "integrity": "sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==",
+            "requires": {
+                "@babel/helper-create-regexp-features-plugin": "^7.22.5",
+                "@babel/helper-plugin-utils": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
+            }
+        },
+        "@babel/preset-env": {
+            "version": "7.22.7",
+            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.7.tgz",
+            "integrity": "sha512-1whfDtW+CzhETuzYXfcgZAh8/GFMeEbz0V5dVgya8YeJyCU6Y/P2Gnx4Qb3MylK68Zu9UiwUvbPMPTpFAOJ+sQ==",
+            "requires": {
+                "@babel/compat-data": "^7.22.6",
+                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-validator-option": "^7.22.5",
+                "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5",
+                "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.5",
+                "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2",
+                "@babel/plugin-syntax-async-generators": "^7.8.4",
+                "@babel/plugin-syntax-class-properties": "^7.12.13",
+                "@babel/plugin-syntax-class-static-block": "^7.14.5",
+                "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+                "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+                "@babel/plugin-syntax-import-assertions": "^7.22.5",
+                "@babel/plugin-syntax-import-attributes": "^7.22.5",
+                "@babel/plugin-syntax-import-meta": "^7.10.4",
+                "@babel/plugin-syntax-json-strings": "^7.8.3",
+                "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+                "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+                "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+                "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+                "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+                "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+                "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+                "@babel/plugin-syntax-top-level-await": "^7.14.5",
+                "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6",
+                "@babel/plugin-transform-arrow-functions": "^7.22.5",
+                "@babel/plugin-transform-async-generator-functions": "^7.22.7",
+                "@babel/plugin-transform-async-to-generator": "^7.22.5",
+                "@babel/plugin-transform-block-scoped-functions": "^7.22.5",
+                "@babel/plugin-transform-block-scoping": "^7.22.5",
+                "@babel/plugin-transform-class-properties": "^7.22.5",
+                "@babel/plugin-transform-class-static-block": "^7.22.5",
+                "@babel/plugin-transform-classes": "^7.22.6",
+                "@babel/plugin-transform-computed-properties": "^7.22.5",
+                "@babel/plugin-transform-destructuring": "^7.22.5",
+                "@babel/plugin-transform-dotall-regex": "^7.22.5",
+                "@babel/plugin-transform-duplicate-keys": "^7.22.5",
+                "@babel/plugin-transform-dynamic-import": "^7.22.5",
+                "@babel/plugin-transform-exponentiation-operator": "^7.22.5",
+                "@babel/plugin-transform-export-namespace-from": "^7.22.5",
+                "@babel/plugin-transform-for-of": "^7.22.5",
+                "@babel/plugin-transform-function-name": "^7.22.5",
+                "@babel/plugin-transform-json-strings": "^7.22.5",
+                "@babel/plugin-transform-literals": "^7.22.5",
+                "@babel/plugin-transform-logical-assignment-operators": "^7.22.5",
+                "@babel/plugin-transform-member-expression-literals": "^7.22.5",
+                "@babel/plugin-transform-modules-amd": "^7.22.5",
+                "@babel/plugin-transform-modules-commonjs": "^7.22.5",
+                "@babel/plugin-transform-modules-systemjs": "^7.22.5",
+                "@babel/plugin-transform-modules-umd": "^7.22.5",
+                "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5",
+                "@babel/plugin-transform-new-target": "^7.22.5",
+                "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.5",
+                "@babel/plugin-transform-numeric-separator": "^7.22.5",
+                "@babel/plugin-transform-object-rest-spread": "^7.22.5",
+                "@babel/plugin-transform-object-super": "^7.22.5",
+                "@babel/plugin-transform-optional-catch-binding": "^7.22.5",
+                "@babel/plugin-transform-optional-chaining": "^7.22.6",
+                "@babel/plugin-transform-parameters": "^7.22.5",
+                "@babel/plugin-transform-private-methods": "^7.22.5",
+                "@babel/plugin-transform-private-property-in-object": "^7.22.5",
+                "@babel/plugin-transform-property-literals": "^7.22.5",
+                "@babel/plugin-transform-regenerator": "^7.22.5",
+                "@babel/plugin-transform-reserved-words": "^7.22.5",
+                "@babel/plugin-transform-shorthand-properties": "^7.22.5",
+                "@babel/plugin-transform-spread": "^7.22.5",
+                "@babel/plugin-transform-sticky-regex": "^7.22.5",
+                "@babel/plugin-transform-template-literals": "^7.22.5",
+                "@babel/plugin-transform-typeof-symbol": "^7.22.5",
+                "@babel/plugin-transform-unicode-escapes": "^7.22.5",
+                "@babel/plugin-transform-unicode-property-regex": "^7.22.5",
+                "@babel/plugin-transform-unicode-regex": "^7.22.5",
+                "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
+                "@babel/preset-modules": "^0.1.5",
+                "@babel/types": "^7.22.5",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3",
+                "babel-plugin-polyfill-corejs2": "^0.4.4",
+                "babel-plugin-polyfill-corejs3": "^0.8.2",
+                "babel-plugin-polyfill-regenerator": "^0.5.1",
+                "core-js-compat": "^3.31.0"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                },
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                }
+            }
+        },
+        "@babel/preset-modules": {
+            "version": "0.1.5",
+            "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz",
+            "integrity": "sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==",
+            "requires": {
+                "@babel/helper-plugin-utils": "^7.0.0",
+                "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+                "@babel/plugin-transform-dotall-regex": "^7.4.4",
+                "@babel/types": "^7.4.4",
+                "esutils": "^2.0.2"
             }
         },
-        "@babel/helper-string-parser": {
-            "version": "7.19.4",
-            "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
-            "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw=="
-        },
-        "@babel/helper-validator-identifier": {
-            "version": "7.19.1",
-            "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
-            "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
-        },
-        "@babel/highlight": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
-            "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+        "@babel/preset-react": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.22.5.tgz",
+            "integrity": "sha512-M+Is3WikOpEJHgR385HbuCITPTaPRaNkibTEa9oiofmJvIsrceb4yp9RL9Kb+TE8LznmeyZqpP+Lopwcx59xPQ==",
             "requires": {
-                "@babel/helper-validator-identifier": "^7.18.6",
-                "chalk": "^2.0.0",
-                "js-tokens": "^4.0.0"
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-validator-option": "^7.22.5",
+                "@babel/plugin-transform-react-display-name": "^7.22.5",
+                "@babel/plugin-transform-react-jsx": "^7.22.5",
+                "@babel/plugin-transform-react-jsx-development": "^7.22.5",
+                "@babel/plugin-transform-react-pure-annotations": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                }
             }
         },
-        "@babel/parser": {
-            "version": "7.20.15",
-            "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz",
-            "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg=="
-        },
-        "@babel/plugin-syntax-jsx": {
-            "version": "7.18.6",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
-            "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+        "@babel/preset-typescript": {
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.22.5.tgz",
+            "integrity": "sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==",
             "requires": {
-                "@babel/helper-plugin-utils": "^7.18.6"
+                "@babel/helper-plugin-utils": "^7.22.5",
+                "@babel/helper-validator-option": "^7.22.5",
+                "@babel/plugin-syntax-jsx": "^7.22.5",
+                "@babel/plugin-transform-modules-commonjs": "^7.22.5",
+                "@babel/plugin-transform-typescript": "^7.22.5"
+            },
+            "dependencies": {
+                "@babel/helper-plugin-utils": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+                    "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+                },
+                "@babel/plugin-syntax-jsx": {
+                    "version": "7.22.5",
+                    "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz",
+                    "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==",
+                    "requires": {
+                        "@babel/helper-plugin-utils": "^7.22.5"
+                    }
+                }
             }
         },
+        "@babel/regjsgen": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz",
+            "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA=="
+        },
         "@babel/runtime": {
             "version": "7.20.13",
             "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
@@ -124,28 +1741,28 @@
             }
         },
         "@babel/template": {
-            "version": "7.20.7",
-            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
-            "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
+            "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
             "requires": {
-                "@babel/code-frame": "^7.18.6",
-                "@babel/parser": "^7.20.7",
-                "@babel/types": "^7.20.7"
+                "@babel/code-frame": "^7.22.5",
+                "@babel/parser": "^7.22.5",
+                "@babel/types": "^7.22.5"
             }
         },
         "@babel/traverse": {
-            "version": "7.20.13",
-            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz",
-            "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==",
-            "requires": {
-                "@babel/code-frame": "^7.18.6",
-                "@babel/generator": "^7.20.7",
-                "@babel/helper-environment-visitor": "^7.18.9",
-                "@babel/helper-function-name": "^7.19.0",
-                "@babel/helper-hoist-variables": "^7.18.6",
-                "@babel/helper-split-export-declaration": "^7.18.6",
-                "@babel/parser": "^7.20.13",
-                "@babel/types": "^7.20.7",
+            "version": "7.22.8",
+            "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz",
+            "integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==",
+            "requires": {
+                "@babel/code-frame": "^7.22.5",
+                "@babel/generator": "^7.22.7",
+                "@babel/helper-environment-visitor": "^7.22.5",
+                "@babel/helper-function-name": "^7.22.5",
+                "@babel/helper-hoist-variables": "^7.22.5",
+                "@babel/helper-split-export-declaration": "^7.22.6",
+                "@babel/parser": "^7.22.7",
+                "@babel/types": "^7.22.5",
                 "debug": "^4.1.0",
                 "globals": "^11.1.0"
             },
@@ -166,12 +1783,12 @@
             }
         },
         "@babel/types": {
-            "version": "7.20.7",
-            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
-            "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+            "version": "7.22.5",
+            "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz",
+            "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
             "requires": {
-                "@babel/helper-string-parser": "^7.19.4",
-                "@babel/helper-validator-identifier": "^7.19.1",
+                "@babel/helper-string-parser": "^7.22.5",
+                "@babel/helper-validator-identifier": "^7.22.5",
                 "to-fast-properties": "^2.0.0"
             }
         },
@@ -283,6 +1900,11 @@
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
                     "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+                },
+                "stylis": {
+                    "version": "4.1.3",
+                    "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
+                    "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
                 }
             }
         },
@@ -392,6 +2014,11 @@
                     "version": "3.1.1",
                     "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
                     "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
+                },
+                "stylis": {
+                    "version": "4.1.3",
+                    "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
+                    "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
                 }
             }
         },
@@ -1064,6 +2691,13 @@
                 "prop-types": "^15.7.2",
                 "react-is": "^16.8.0 || ^17.0.0",
                 "react-transition-group": "^4.4.0"
+            },
+            "dependencies": {
+                "popper.js": {
+                    "version": "1.16.1-lts",
+                    "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
+                    "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+                }
             }
         },
         "@material-ui/styles": {
@@ -1298,6 +2932,25 @@
                 }
             }
         },
+        "@mui/styled-engine-sc": {
+            "version": "5.12.0",
+            "resolved": "https://registry.npmjs.org/@mui/styled-engine-sc/-/styled-engine-sc-5.12.0.tgz",
+            "integrity": "sha512-3MgYoY2YG5tx0E5oKqvCv94oL0ABVBr+qpcyvciXW/v0wzPG6bXvuZV80GHYlJfasgnnRa1AbRWf5a9FcX8v6g==",
+            "requires": {
+                "@babel/runtime": "^7.21.0",
+                "prop-types": "^15.8.1"
+            },
+            "dependencies": {
+                "@babel/runtime": {
+                    "version": "7.22.6",
+                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                    "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                    "requires": {
+                        "regenerator-runtime": "^0.13.11"
+                    }
+                }
+            }
+        },
         "@mui/system": {
             "version": "5.13.1",
             "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.1.tgz",
@@ -1368,6 +3021,12 @@
                 }
             }
         },
+        "@nicolo-ribaudo/chokidar-2": {
+            "version": "2.1.8-no-fsevents.3",
+            "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz",
+            "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==",
+            "optional": true
+        },
         "@nodelib/fs.scandir": {
             "version": "2.1.5",
             "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2583,14 +4242,6 @@
                 "@types/react": "*",
                 "date-fns": "^2.0.1",
                 "popper.js": "^1.14.1"
-            },
-            "dependencies": {
-                "popper.js": {
-                    "version": "1.16.1",
-                    "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
-                    "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
-                    "dev": true
-                }
             }
         },
         "@types/react-dom": {
@@ -2620,6 +4271,14 @@
                 "react-icons": "*"
             }
         },
+        "@types/react-is": {
+            "version": "18.2.1",
+            "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz",
+            "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==",
+            "requires": {
+                "@types/react": "*"
+            }
+        },
         "@types/react-measure": {
             "version": "2.0.8",
             "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.8.tgz",
@@ -2828,6 +4487,11 @@
             "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
             "dev": true
         },
+        "@types/stylis": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz",
+            "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw=="
+        },
         "@types/supercluster": {
             "version": "7.1.0",
             "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.0.tgz",
@@ -3193,8 +4857,8 @@
         },
         "D": {
             "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/D/-/D-1.0.0.tgz",
-            "integrity": "sha512-nQvrCBu7K2pSSEtIM0EEF03FVjcczCXInMt3moLNFbjlWx6bZrX72uT6/1uAXDbnzGUAx9gTyDiQ+vrFi663oA=="
+            "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA=="
         },
         "abab": {
             "version": "2.0.6",
@@ -4102,6 +5766,40 @@
                 "resolve": "^1.12.0"
             }
         },
+        "babel-plugin-polyfill-corejs2": {
+            "version": "0.4.4",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz",
+            "integrity": "sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA==",
+            "requires": {
+                "@babel/compat-data": "^7.22.6",
+                "@babel/helper-define-polyfill-provider": "^0.4.1",
+                "@nicolo-ribaudo/semver-v6": "^6.3.3"
+            },
+            "dependencies": {
+                "@nicolo-ribaudo/semver-v6": {
+                    "version": "6.3.3",
+                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
+                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                }
+            }
+        },
+        "babel-plugin-polyfill-corejs3": {
+            "version": "0.8.2",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz",
+            "integrity": "sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ==",
+            "requires": {
+                "@babel/helper-define-polyfill-provider": "^0.4.1",
+                "core-js-compat": "^3.31.0"
+            }
+        },
+        "babel-plugin-polyfill-regenerator": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz",
+            "integrity": "sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw==",
+            "requires": {
+                "@babel/helper-define-polyfill-provider": "^0.4.1"
+            }
+        },
         "babel-plugin-styled-components": {
             "version": "2.0.7",
             "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz",
@@ -4483,30 +6181,349 @@
                     "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.0"
+                    }
+                }
+            }
+        },
+        "brotli": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
+            "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
+            "requires": {
+                "base64-js": "^1.1.2"
+            }
+        },
+        "browndash-components": {
+            "version": "0.0.42",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.42.tgz",
+            "integrity": "sha512-GRw4Jx5ZM08zk4W8HGPo2U/Q5zrDJ+d3pbLEj42TJKDkzsQ+SNK2y6RovJTR5SiavrmTx0JZYv902378QZ2u1g==",
+            "requires": {
+                "@emotion/react": "^11.11.1",
+                "@emotion/styled": "^11.11.0",
+                "@mui/material": "^5.13.7",
+                "@mui/styled-engine-sc": "^5.12.0",
+                "color": "^4.2.3",
+                "react-color": "^2.19.3",
+                "react-icons": "^4.3.1",
+                "react-measure": "^2.5.2",
+                "styled-components": "^6.0.3"
+            },
+            "dependencies": {
+                "@babel/cli": {
+                    "version": "7.22.6",
+                    "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.6.tgz",
+                    "integrity": "sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw==",
+                    "requires": {
+                        "@jridgewell/trace-mapping": "^0.3.17",
+                        "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3",
+                        "chokidar": "^3.4.0",
+                        "commander": "^4.0.1",
+                        "convert-source-map": "^1.1.0",
+                        "fs-readdir-recursive": "^1.1.0",
+                        "glob": "^7.2.0",
+                        "make-dir": "^2.1.0",
+                        "slash": "^2.0.0"
+                    }
+                },
+                "@emotion/babel-plugin": {
+                    "version": "11.11.0",
+                    "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz",
+                    "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==",
+                    "requires": {
+                        "@babel/helper-module-imports": "^7.16.7",
+                        "@babel/runtime": "^7.18.3",
+                        "@emotion/hash": "^0.9.1",
+                        "@emotion/memoize": "^0.8.1",
+                        "@emotion/serialize": "^1.1.2",
+                        "babel-plugin-macros": "^3.1.0",
+                        "convert-source-map": "^1.5.0",
+                        "escape-string-regexp": "^4.0.0",
+                        "find-root": "^1.1.0",
+                        "source-map": "^0.5.7",
+                        "stylis": "4.2.0"
+                    }
+                },
+                "@emotion/cache": {
+                    "version": "11.11.0",
+                    "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz",
+                    "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==",
+                    "requires": {
+                        "@emotion/memoize": "^0.8.1",
+                        "@emotion/sheet": "^1.2.2",
+                        "@emotion/utils": "^1.2.1",
+                        "@emotion/weak-memoize": "^0.3.1",
+                        "stylis": "4.2.0"
+                    }
+                },
+                "@emotion/hash": {
+                    "version": "0.9.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz",
+                    "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ=="
+                },
+                "@emotion/memoize": {
+                    "version": "0.8.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
+                    "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
+                },
+                "@emotion/react": {
+                    "version": "11.11.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz",
+                    "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==",
+                    "requires": {
+                        "@babel/runtime": "^7.18.3",
+                        "@emotion/babel-plugin": "^11.11.0",
+                        "@emotion/cache": "^11.11.0",
+                        "@emotion/serialize": "^1.1.2",
+                        "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1",
+                        "@emotion/utils": "^1.2.1",
+                        "@emotion/weak-memoize": "^0.3.1",
+                        "hoist-non-react-statics": "^3.3.1"
+                    }
+                },
+                "@emotion/serialize": {
+                    "version": "1.1.2",
+                    "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.2.tgz",
+                    "integrity": "sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==",
+                    "requires": {
+                        "@emotion/hash": "^0.9.1",
+                        "@emotion/memoize": "^0.8.1",
+                        "@emotion/unitless": "^0.8.1",
+                        "@emotion/utils": "^1.2.1",
+                        "csstype": "^3.0.2"
+                    }
+                },
+                "@emotion/sheet": {
+                    "version": "1.2.2",
+                    "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz",
+                    "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA=="
+                },
+                "@emotion/unitless": {
+                    "version": "0.8.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+                    "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
+                },
+                "@emotion/utils": {
+                    "version": "1.2.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz",
+                    "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg=="
+                },
+                "@emotion/weak-memoize": {
+                    "version": "0.3.1",
+                    "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz",
+                    "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww=="
+                },
+                "@mui/base": {
+                    "version": "5.0.0-beta.6",
+                    "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.6.tgz",
+                    "integrity": "sha512-jcHy6HwOX7KzRhRtL8nvIvUlxvLx2Fl6NMRCyUSQSvMTyfou9kndekz0H4HJaXvG1Y4WEifk23RYedOlrD1kEQ==",
+                    "requires": {
+                        "@babel/runtime": "^7.22.5",
+                        "@emotion/is-prop-valid": "^1.2.1",
+                        "@mui/types": "^7.2.4",
+                        "@mui/utils": "^5.13.7",
+                        "@popperjs/core": "^2.11.8",
+                        "clsx": "^1.2.1",
+                        "prop-types": "^15.8.1",
+                        "react-is": "^18.2.0"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@mui/core-downloads-tracker": {
+                    "version": "5.13.7",
+                    "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.7.tgz",
+                    "integrity": "sha512-/suIo4WoeL/OyO3KUsFVpdOmKiSAr6NpWXmQ4WLSxwKrTiha1FJxM6vwAki5W/5kR9WnVLw5E8JC4oHHsutT8w=="
+                },
+                "@mui/material": {
+                    "version": "5.13.7",
+                    "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.7.tgz",
+                    "integrity": "sha512-+n453jDDm88zZM3b5YK29nZ7gXY+s+rryH9ovDbhmfSkOlFtp+KSqbXy5cTaC/UlDqDM7sYYJGq8BmJov3v9Tg==",
+                    "requires": {
+                        "@babel/runtime": "^7.22.5",
+                        "@mui/base": "5.0.0-beta.6",
+                        "@mui/core-downloads-tracker": "^5.13.7",
+                        "@mui/system": "^5.13.7",
+                        "@mui/types": "^7.2.4",
+                        "@mui/utils": "^5.13.7",
+                        "@types/react-transition-group": "^4.4.6",
+                        "clsx": "^1.2.1",
+                        "csstype": "^3.1.2",
+                        "prop-types": "^15.8.1",
+                        "react-is": "^18.2.0",
+                        "react-transition-group": "^4.4.5"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@mui/private-theming": {
+                    "version": "5.13.7",
+                    "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz",
+                    "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==",
+                    "requires": {
+                        "@babel/runtime": "^7.22.5",
+                        "@mui/utils": "^5.13.7",
+                        "prop-types": "^15.8.1"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@mui/styled-engine": {
+                    "version": "5.13.2",
+                    "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz",
+                    "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==",
+                    "requires": {
+                        "@babel/runtime": "^7.21.0",
+                        "@emotion/cache": "^11.11.0",
+                        "csstype": "^3.1.2",
+                        "prop-types": "^15.8.1"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@mui/system": {
+                    "version": "5.13.7",
+                    "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.7.tgz",
+                    "integrity": "sha512-7R2KdI6vr8KtnauEfg9e9xQmPk6Gg/1vGNiALYyhSI+cYztxN6WmlSqGX4bjWn/Sygp1TUE1jhFEgs7MWruhkQ==",
+                    "requires": {
+                        "@babel/runtime": "^7.22.5",
+                        "@mui/private-theming": "^5.13.7",
+                        "@mui/styled-engine": "^5.13.2",
+                        "@mui/types": "^7.2.4",
+                        "@mui/utils": "^5.13.7",
+                        "clsx": "^1.2.1",
+                        "csstype": "^3.1.2",
+                        "prop-types": "^15.8.1"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@mui/utils": {
+                    "version": "5.13.7",
+                    "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.7.tgz",
+                    "integrity": "sha512-/3BLptG/q0u36eYED7Nhf4fKXmcKb6LjjT7ZMwhZIZSdSxVqDqSTmATW3a56n3KEPQUXCU9TpxAfCBQhs6brVA==",
+                    "requires": {
+                        "@babel/runtime": "^7.22.5",
+                        "@types/prop-types": "^15.7.5",
+                        "@types/react-is": "^18.2.1",
+                        "prop-types": "^15.8.1",
+                        "react-is": "^18.2.0"
+                    },
+                    "dependencies": {
+                        "@babel/runtime": {
+                            "version": "7.22.6",
+                            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
+                            "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
+                            "requires": {
+                                "regenerator-runtime": "^0.13.11"
+                            }
+                        }
+                    }
+                },
+                "@popperjs/core": {
+                    "version": "2.11.8",
+                    "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+                    "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
+                },
+                "@types/react-transition-group": {
+                    "version": "4.4.6",
+                    "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz",
+                    "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==",
+                    "requires": {
+                        "@types/react": "*"
                     }
-                }
-            }
-        },
-        "brotli": {
-            "version": "1.3.3",
-            "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
-            "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
-            "requires": {
-                "base64-js": "^1.1.2"
-            }
-        },
-        "browndash-components": {
-            "version": "0.0.35",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.35.tgz",
-            "integrity": "sha512-xHScZmY6y7s3RH7N4rQ4oEu0iAeeP4FbR2Nv289JREThcqiHQqII7vV4rF0tiL9jJepwGLaSIO3k45kUhm62ZQ==",
-            "requires": {
-                "color": "^4.2.3",
-                "react-color": "^2.19.3",
-                "react-icons": "^4.3.1",
-                "react-measure": "^2.5.2"
-            },
-            "dependencies": {
+                },
+                "anymatch": {
+                    "version": "3.1.3",
+                    "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+                    "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+                    "optional": true,
+                    "requires": {
+                        "normalize-path": "^3.0.0",
+                        "picomatch": "^2.0.4"
+                    }
+                },
+                "babel-plugin-macros": {
+                    "version": "3.1.0",
+                    "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+                    "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+                    "requires": {
+                        "@babel/runtime": "^7.12.5",
+                        "cosmiconfig": "^7.0.0",
+                        "resolve": "^1.19.0"
+                    }
+                },
+                "binary-extensions": {
+                    "version": "2.2.0",
+                    "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+                    "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+                    "optional": true
+                },
+                "braces": {
+                    "version": "3.0.2",
+                    "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+                    "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+                    "optional": true,
+                    "requires": {
+                        "fill-range": "^7.0.1"
+                    }
+                },
+                "chokidar": {
+                    "version": "3.5.3",
+                    "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+                    "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+                    "optional": true,
+                    "requires": {
+                        "anymatch": "~3.1.2",
+                        "braces": "~3.0.2",
+                        "fsevents": "~2.3.2",
+                        "glob-parent": "~5.1.2",
+                        "is-binary-path": "~2.1.0",
+                        "is-glob": "~4.0.1",
+                        "normalize-path": "~3.0.0",
+                        "readdirp": "~3.6.0"
+                    }
+                },
                 "color": {
                     "version": "4.2.3",
                     "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz",
@@ -4528,6 +6545,182 @@
                     "version": "1.1.4",
                     "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
                     "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+                },
+                "commander": {
+                    "version": "4.1.1",
+                    "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+                    "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="
+                },
+                "cosmiconfig": {
+                    "version": "7.1.0",
+                    "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+                    "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+                    "requires": {
+                        "@types/parse-json": "^4.0.0",
+                        "import-fresh": "^3.2.1",
+                        "parse-json": "^5.0.0",
+                        "path-type": "^4.0.0",
+                        "yaml": "^1.10.0"
+                    }
+                },
+                "css-to-react-native": {
+                    "version": "3.2.0",
+                    "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+                    "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+                    "requires": {
+                        "camelize": "^1.0.0",
+                        "css-color-keywords": "^1.0.0",
+                        "postcss-value-parser": "^4.0.2"
+                    }
+                },
+                "csstype": {
+                    "version": "3.1.2",
+                    "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+                    "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+                },
+                "escape-string-regexp": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+                    "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
+                },
+                "fill-range": {
+                    "version": "7.0.1",
+                    "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+                    "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+                    "optional": true,
+                    "requires": {
+                        "to-regex-range": "^5.0.1"
+                    }
+                },
+                "fsevents": {
+                    "version": "2.3.2",
+                    "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+                    "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+                    "optional": true
+                },
+                "glob-parent": {
+                    "version": "5.1.2",
+                    "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+                    "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+                    "optional": true,
+                    "requires": {
+                        "is-glob": "^4.0.1"
+                    }
+                },
+                "is-binary-path": {
+                    "version": "2.1.0",
+                    "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+                    "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+                    "optional": true,
+                    "requires": {
+                        "binary-extensions": "^2.0.0"
+                    }
+                },
+                "is-number": {
+                    "version": "7.0.0",
+                    "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+                    "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+                    "optional": true
+                },
+                "make-dir": {
+                    "version": "2.1.0",
+                    "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+                    "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+                    "requires": {
+                        "pify": "^4.0.1",
+                        "semver": "^5.6.0"
+                    }
+                },
+                "nanoid": {
+                    "version": "3.3.6",
+                    "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
+                    "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
+                },
+                "pify": {
+                    "version": "4.0.1",
+                    "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+                    "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
+                },
+                "postcss": {
+                    "version": "8.4.25",
+                    "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz",
+                    "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==",
+                    "requires": {
+                        "nanoid": "^3.3.6",
+                        "picocolors": "^1.0.0",
+                        "source-map-js": "^1.0.2"
+                    }
+                },
+                "postcss-value-parser": {
+                    "version": "4.2.0",
+                    "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
+                    "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
+                },
+                "react-is": {
+                    "version": "18.2.0",
+                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+                    "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+                },
+                "readdirp": {
+                    "version": "3.6.0",
+                    "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+                    "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+                    "optional": true,
+                    "requires": {
+                        "picomatch": "^2.2.1"
+                    }
+                },
+                "slash": {
+                    "version": "2.0.0",
+                    "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+                    "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A=="
+                },
+                "styled-components": {
+                    "version": "6.0.3",
+                    "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.3.tgz",
+                    "integrity": "sha512-qEyWvDK4CYCyDckNIruRJIcQSvcUR3dVEw/fwxu1v0LFzUMPr2uf5PhXHp17FkGK+S4TkglOS+XIealo1MssQA==",
+                    "requires": {
+                        "@babel/cli": "^7.21.0",
+                        "@babel/core": "^7.21.0",
+                        "@babel/helper-module-imports": "^7.18.6",
+                        "@babel/plugin-external-helpers": "^7.18.6",
+                        "@babel/plugin-proposal-class-properties": "^7.18.6",
+                        "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
+                        "@babel/preset-env": "^7.20.2",
+                        "@babel/preset-react": "^7.18.6",
+                        "@babel/preset-typescript": "^7.21.0",
+                        "@babel/traverse": "^7.21.2",
+                        "@emotion/is-prop-valid": "^1.2.1",
+                        "@emotion/unitless": "^0.8.0",
+                        "@types/stylis": "^4.0.2",
+                        "css-to-react-native": "^3.2.0",
+                        "csstype": "^3.1.2",
+                        "postcss": "^8.4.23",
+                        "shallowequal": "^1.1.0",
+                        "stylis": "^4.3.0",
+                        "tslib": "^2.5.0"
+                    },
+                    "dependencies": {
+                        "stylis": {
+                            "version": "4.3.0",
+                            "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz",
+                            "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ=="
+                        }
+                    }
+                },
+                "stylis": {
+                    "version": "4.2.0",
+                    "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+                    "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
+                },
+                "to-regex-range": {
+                    "version": "5.0.1",
+                    "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+                    "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+                    "optional": true,
+                    "requires": {
+                        "is-number": "^7.0.0"
+                    }
                 }
             }
         },
@@ -4548,14 +6741,14 @@
             "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
         },
         "browserslist": {
-            "version": "4.21.5",
-            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
-            "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
+            "version": "4.21.9",
+            "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
+            "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
             "requires": {
-                "caniuse-lite": "^1.0.30001449",
-                "electron-to-chromium": "^1.4.284",
-                "node-releases": "^2.0.8",
-                "update-browserslist-db": "^1.0.10"
+                "caniuse-lite": "^1.0.30001503",
+                "electron-to-chromium": "^1.4.431",
+                "node-releases": "^2.0.12",
+                "update-browserslist-db": "^1.0.11"
             }
         },
         "bson": {
@@ -4788,9 +6981,9 @@
             "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ=="
         },
         "caniuse-lite": {
-            "version": "1.0.30001451",
-            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz",
-            "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w=="
+            "version": "1.0.30001514",
+            "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz",
+            "integrity": "sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ=="
         },
         "canvas": {
             "version": "2.11.0",
@@ -5602,6 +7795,14 @@
             "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.28.0.tgz",
             "integrity": "sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw=="
         },
+        "core-js-compat": {
+            "version": "3.31.1",
+            "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.31.1.tgz",
+            "integrity": "sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==",
+            "requires": {
+                "browserslist": "^4.21.9"
+            }
+        },
         "core-js-pure": {
             "version": "3.28.0",
             "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.28.0.tgz",
@@ -5955,6 +8156,16 @@
             "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
             "dev": true
         },
+        "d": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+            "dev": true,
+            "requires": {
+                "es5-ext": "^0.10.50",
+                "type": "^1.0.1"
+            }
+        },
         "d3": {
             "version": "7.8.4",
             "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz",
@@ -7050,9 +9261,9 @@
             "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
         "electron-to-chromium": {
-            "version": "1.4.295",
-            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz",
-            "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw=="
+            "version": "1.4.454",
+            "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.454.tgz",
+            "integrity": "sha512-pmf1rbAStw8UEQ0sr2cdJtWl48ZMuPD9Sto8HVQOq9vx9j2WgDEN6lYoaqFvqEHYOmGA9oRGn7LqWI9ta0YugQ=="
         },
         "emoji-regex": {
             "version": "7.0.3",
@@ -7335,6 +9546,28 @@
                 "is-symbol": "^1.0.2"
             }
         },
+        "es5-ext": {
+            "version": "0.10.62",
+            "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+            "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+            "dev": true,
+            "requires": {
+                "es6-iterator": "^2.0.3",
+                "es6-symbol": "^3.1.3",
+                "next-tick": "^1.1.0"
+            }
+        },
+        "es6-iterator": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+            "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+            "dev": true,
+            "requires": {
+                "d": "1",
+                "es5-ext": "^0.10.35",
+                "es6-symbol": "^3.1.1"
+            }
+        },
         "es6-promise": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
@@ -7346,6 +9579,7 @@
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
             "dev": true,
             "requires": {
+                "d": "^1.0.1",
                 "ext": "^1.1.2"
             }
         },
@@ -9700,6 +11934,11 @@
             "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
             "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q=="
         },
+        "fs-readdir-recursive": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+            "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA=="
+        },
         "fs-write-stream-atomic": {
             "version": "1.0.10",
             "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
@@ -9897,6 +12136,11 @@
                 "json-bigint": "^0.3.0"
             }
         },
+        "gensync": {
+            "version": "1.0.0-beta.2",
+            "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+            "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+        },
         "get-caller-file": {
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -14042,9 +16286,9 @@
             }
         },
         "node-releases": {
-            "version": "2.0.10",
-            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
-            "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w=="
+            "version": "2.0.13",
+            "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+            "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
         },
         "node-sass": {
             "version": "4.14.1",
@@ -18752,9 +20996,9 @@
             "dev": true
         },
         "popper.js": {
-            "version": "1.16.1-lts",
-            "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1-lts.tgz",
-            "integrity": "sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA=="
+            "version": "1.16.1",
+            "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+            "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
         },
         "portfinder": {
             "version": "1.0.32",
@@ -19916,11 +22160,6 @@
                 "warning": "^4.0.2"
             },
             "dependencies": {
-                "popper.js": {
-                    "version": "1.16.1",
-                    "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
-                    "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
-                },
                 "warning": {
                     "version": "4.0.3",
                     "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
@@ -20298,11 +22537,32 @@
                 "@babel/runtime": "^7.9.2"
             }
         },
+        "regenerate": {
+            "version": "1.4.2",
+            "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+            "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
+        },
+        "regenerate-unicode-properties": {
+            "version": "10.1.0",
+            "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz",
+            "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==",
+            "requires": {
+                "regenerate": "^1.4.2"
+            }
+        },
         "regenerator-runtime": {
             "version": "0.13.11",
             "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
             "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
         },
+        "regenerator-transform": {
+            "version": "0.15.1",
+            "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.1.tgz",
+            "integrity": "sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==",
+            "requires": {
+                "@babel/runtime": "^7.8.4"
+            }
+        },
         "regex-not": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
@@ -20333,6 +22593,19 @@
             "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
             "dev": true
         },
+        "regexpu-core": {
+            "version": "5.3.2",
+            "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz",
+            "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==",
+            "requires": {
+                "@babel/regjsgen": "^0.8.0",
+                "regenerate": "^1.4.2",
+                "regenerate-unicode-properties": "^10.1.0",
+                "regjsparser": "^0.9.1",
+                "unicode-match-property-ecmascript": "^2.0.0",
+                "unicode-match-property-value-ecmascript": "^2.1.0"
+            }
+        },
         "registry-auth-token": {
             "version": "3.4.0",
             "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
@@ -20350,6 +22623,21 @@
                 "rc": "^1.0.1"
             }
         },
+        "regjsparser": {
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
+            "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==",
+            "requires": {
+                "jsesc": "~0.5.0"
+            },
+            "dependencies": {
+                "jsesc": {
+                    "version": "0.5.0",
+                    "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+                    "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA=="
+                }
+            }
+        },
         "rehype-raw": {
             "version": "6.1.1",
             "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz",
@@ -21182,6 +23470,11 @@
             "resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.2.1.tgz",
             "integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA=="
         },
+        "shallowequal": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+            "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+        },
         "sharp": {
             "version": "0.23.4",
             "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.23.4.tgz",
@@ -21708,6 +24001,11 @@
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
             "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
         },
+        "source-map-js": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
+            "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="
+        },
         "source-map-resolve": {
             "version": "0.5.3",
             "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
@@ -22191,18 +24489,13 @@
                     "requires": {
                         "@emotion/memoize": "0.7.4"
                     }
-                },
-                "stylis": {
-                    "version": "3.5.4",
-                    "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
-                    "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q=="
                 }
             }
         },
         "stylis": {
-            "version": "4.1.3",
-            "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz",
-            "integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
+            "version": "3.5.4",
+            "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz",
+            "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q=="
         },
         "stylis-rule-sheet": {
             "version": "0.0.10",
@@ -22515,7 +24808,7 @@
         "to-fast-properties": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-            "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+            "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
         },
         "to-object-path": {
             "version": "0.3.0",
@@ -23018,6 +25311,12 @@
             "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
             "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
         },
+        "type": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+            "dev": true
+        },
         "type-check": {
             "version": "0.4.0",
             "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -23219,6 +25518,30 @@
             "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
             "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
         },
+        "unicode-canonical-property-names-ecmascript": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
+            "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ=="
+        },
+        "unicode-match-property-ecmascript": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz",
+            "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==",
+            "requires": {
+                "unicode-canonical-property-names-ecmascript": "^2.0.0",
+                "unicode-property-aliases-ecmascript": "^2.0.0"
+            }
+        },
+        "unicode-match-property-value-ecmascript": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz",
+            "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA=="
+        },
+        "unicode-property-aliases-ecmascript": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz",
+            "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w=="
+        },
         "unicode-trie": {
             "version": "0.3.1",
             "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz",
@@ -23418,9 +25741,9 @@
             "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
         },
         "update-browserslist-db": {
-            "version": "1.0.10",
-            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
-            "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz",
+            "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==",
             "requires": {
                 "escalade": "^3.1.1",
                 "picocolors": "^1.0.0"
diff --git a/package.json b/package.json
index da3097bf4..5519e0c17 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.35",
+        "browndash-components": "0.0.42",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ec529afc3..805002452 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -138,7 +138,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             // assuming we need to get rowSpan because we might be dealing with many columns. Grid gap makes sense if multiple columns
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
             // just getting the style
-            const style = this.isStackingView ? { background: Colors.MEDIUM_GRAY, width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             // So we're choosing whether we're going to render a column or a masonry doc
             return (
                 <div className={`collectionStackingView-${this.isStackingView ? 'columnDoc' : 'masonryDoc'}`} key={d[Id]} style={style}>
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index e2fe0bcf1..b9f75444f 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -475,7 +475,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             );
         console.log("switchToggle", switchToggle, this.rootDoc.title)
         return (
-            <Toggle toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
+            <Toggle tooltip={this.label} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
         )
 
         if (switchToggle) {
diff --git a/src/client/views/topbar/TopBar.scss b/src/client/views/topbar/TopBar.scss
index ede59a910..2237d5ac1 100644
--- a/src/client/views/topbar/TopBar.scss
+++ b/src/client/views/topbar/TopBar.scss
@@ -1,22 +1,6 @@
 @import '../global/globalCssVariables';
 
-.iconButton-container.primary {
-    color: white;
-    .iconButton-background {
-        filter: unset;
-        background: transparent;
-    }
-}
-.topbarHeart-red {
-    .iconButton-container.primary {
-        .iconButton-content {
-            color: red;
-        }
-        .iconButton-background {
-            background: black;
-        }
-    }
-}
+
 .topbar-container {
     flex-direction: column;
     font-size: 10px;
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 1d9c25e3c..a73d5cce0 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -147,21 +147,17 @@ export class TopBar extends React.Component {
                     }}
                     size={Size.SMALL}
                 />}
-                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
-                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
-                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
-                <IconButton size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
-                <Tooltip title={<div className="dash-tooltip">{'Server connection ' + (PingManager.Instance.IsBeating ? 'active' : 'broken')}</div>}>
-                    <div className={'topbarHeart' + (this.happyHeart ? '' : '-red')}>
-                        <IconButton
-                            size={Size.SMALL}
-                            onClick={PingManager.Instance.showAlert}
-                            tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
-                            color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
-                            icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
-                        />
-                    </div>
-                </Tooltip>
+                <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
+                <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
+                <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
+                <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
+                <IconButton
+                    size={Size.SMALL}
+                    onClick={PingManager.Instance.showAlert}
+                    tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
+                    color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
+                    icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
+                />
                 {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.textColor} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
             </div>
         );
diff --git a/src/server/DashSession/Session/utilities/session_config.ts b/src/server/DashSession/Session/utilities/session_config.ts
index bde98e9d2..266759929 100644
--- a/src/server/DashSession/Session/utilities/session_config.ts
+++ b/src/server/DashSession/Session/utilities/session_config.ts
@@ -120,7 +120,7 @@ export const defaultConfig: Configuration = {
             color: "green"
         }
     },
-    ports: { server: 3000 },
+    ports: { server: 1050 },
     polling: {
         route: "/",
         intervalSeconds: 30,
diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts
index 15088ddb2..805da1d43 100644
--- a/src/server/server_Initialization.ts
+++ b/src/server/server_Initialization.ts
@@ -34,7 +34,7 @@ const compiler = webpack(config);
 export type RouteSetter = (server: RouteManager) => void;
 //export let disconnect: Function;
 
-export let resolvedPorts: { server: number; socket: number } = { server: 3000, socket: 4321 };
+export let resolvedPorts: { server: number; socket: number } = { server: 1050, socket: 4321 };
 export let resolvedServerUrl: string;
 
 export default async function InitializeServer(routeSetter: RouteSetter) {
-- 
cgit v1.2.3-70-g09d2


From 10ed9b42d8fd56364ca8dcfd5b9005fae28b305f Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Sun, 9 Jul 2023 20:08:14 -0400
Subject: fixing dropdown components

---
 package-lock.json                             | 25 ++++----
 package.json                                  |  2 +-
 src/client/util/CurrentUserUtils.ts           | 28 ++++----
 src/client/views/nodes/button/FontIconBox.tsx | 92 ++++++++-------------------
 src/client/views/topbar/TopBar.tsx            | 13 ++--
 5 files changed, 57 insertions(+), 103 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/package-lock.json b/package-lock.json
index c48c57357..d938d9658 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4856,9 +4856,13 @@
             "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg="
         },
         "D": {
-            "version": "1.0.0",
+            "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
-            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA=="
+            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+            "requires": {
+                "es5-ext": "^0.10.50",
+                "type": "^1.0.1"
+            }
         },
         "abab": {
             "version": "2.0.6",
@@ -6195,9 +6199,9 @@
             }
         },
         "browndash-components": {
-            "version": "0.0.42",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.42.tgz",
-            "integrity": "sha512-GRw4Jx5ZM08zk4W8HGPo2U/Q5zrDJ+d3pbLEj42TJKDkzsQ+SNK2y6RovJTR5SiavrmTx0JZYv902378QZ2u1g==",
+            "version": "0.0.47",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.47.tgz",
+            "integrity": "sha512-eFiTens6b8+lizT8gkSMZJW7cbroq2chUppLDd4xTlXGUGNwd1qPL+KIF4L21DY4tDouZVKtKI32gODWlIKkjw==",
             "requires": {
                 "@emotion/react": "^11.11.1",
                 "@emotion/styled": "^11.11.0",
@@ -8160,7 +8164,6 @@
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
             "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
-            "dev": true,
             "requires": {
                 "es5-ext": "^0.10.50",
                 "type": "^1.0.1"
@@ -9550,7 +9553,6 @@
             "version": "0.10.62",
             "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
             "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
-            "dev": true,
             "requires": {
                 "es6-iterator": "^2.0.3",
                 "es6-symbol": "^3.1.3",
@@ -9561,7 +9563,6 @@
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
             "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
-            "dev": true,
             "requires": {
                 "d": "1",
                 "es5-ext": "^0.10.35",
@@ -9577,7 +9578,6 @@
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
-            "dev": true,
             "requires": {
                 "d": "^1.0.1",
                 "ext": "^1.1.2"
@@ -11202,7 +11202,6 @@
             "version": "1.7.0",
             "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
             "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
-            "dev": true,
             "requires": {
                 "type": "^2.7.2"
             },
@@ -11210,8 +11209,7 @@
                 "type": {
                     "version": "2.7.2",
                     "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
-                    "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==",
-                    "dev": true
+                    "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
                 }
             }
         },
@@ -25314,8 +25312,7 @@
         "type": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
-            "dev": true
+            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
         },
         "type-check": {
             "version": "0.4.0",
diff --git a/package.json b/package.json
index 5519e0c17..2bfd01211 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.42",
+        "browndash-components": "0.0.47",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 4c5fea260..3475cab82 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -338,19 +338,19 @@ export class CurrentUserUtils {
     }
 
     /// returns descriptions needed to buttons for the left sidebar to open up panes displaying different collections of documents
-    static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] {
+    static leftSidebarMenuBtnDescriptions(doc: Doc):{title:string, target:Doc, icon:string, toolTip: string, scripts:{[key:string]:any}, funcs?:{[key:string]:any}}[] {
       const badgeValue = "((len) => len && len !== '0' ? len: undefined)(docList(self.target.data).filter(doc => !docList(self.target.viewed).includes(doc)).length.toString())"; 
       const getActiveDashTrails = "Doc.ActiveDashboard?.myTrails";
         return [
-            { title: "Dashboards",      target: this.setupDashboards(doc, "myDashboards"),         icon: "desktop",     funcs: {hidden: "IsNoviceMode()"} },
-            { title: "Search",          target: this.setupSearcher(doc, "mySearcher"),             icon: "search",      },
-            { title: "Files",           target: this.setupFilesystem(doc, "myFilesystem"),         icon: "folder-open", },
-            { title: "Tools",           target: this.setupToolsBtnPanel(doc, "myTools"),           icon: "wrench",      funcs: {hidden: "IsNoviceMode()"} },
-            { title: "Imports",         target: this.setupImportSidebar(doc, "myImports"),         icon: "upload",      },
-            { title: "Recently Closed", target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive",     },
-            { title: "Shared Docs",     target: Doc.MySharedDocs,                                  icon: "users",       funcs: {badgeValue:badgeValue}},
-            { title: "Trails",          target: Doc.UserDoc(),                                     icon: "pres-trail",  funcs: {target: getActiveDashTrails}},
-            { title: "User Doc View",   target: this.setupUserDocView(doc, "myUserDocView"),       icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
+            { title: "Dashboards",      toolTip: "Dashboards ⌘D",       target: this.setupDashboards(doc, "myDashboards"),         icon: "desktop",     funcs: {hidden: "IsNoviceMode()"} },
+            { title: "Search",          toolTip: "Search ⌘F",           target: this.setupSearcher(doc, "mySearcher"),             icon: "search",      },
+            { title: "Files",           toolTip: "Files ⌘⇧F",           target: this.setupFilesystem(doc, "myFilesystem"),         icon: "folder-open", },
+            { title: "Tools",           toolTip: "Tools ⌘T",            target: this.setupToolsBtnPanel(doc, "myTools"),           icon: "wrench",      funcs: {hidden: "IsNoviceMode()"} },
+            { title: "Imports",         toolTip: "Imports ⌘I",          target: this.setupImportSidebar(doc, "myImports"),         icon: "upload",      },
+            { title: "Recently Closed", toolTip: "Recently Closed ⌘R",  target: this.setupRecentlyClosed(doc, "myRecentlyClosed"), icon: "archive",     },
+            { title: "Shared Docs",     toolTip: "Shared Docs ⌘⇧S",     target: Doc.MySharedDocs,                                  icon: "users",       funcs: {badgeValue:badgeValue}},
+            { title: "Trails",          toolTip: "Trails ⌘⇧",           target: Doc.UserDoc(),                                     icon: "pres-trail",  funcs: {target: getActiveDashTrails}},
+            { title: "User Doc View",   toolTip: "User Doc ⌘U",         target: this.setupUserDocView(doc, "myUserDocView"),       icon: "address-card",funcs: {hidden: "IsNoviceMode()"} },
         ].map(tuple => ({...tuple, scripts:{onClick: 'selectMainMenu(self)'}}));
     }
 
@@ -363,10 +363,10 @@ export class CurrentUserUtils {
     static setupLeftSidebarMenu(doc: Doc, field="myLeftSidebarMenu") {
         this.setupLeftSidebarPanel(doc);
         const myLeftSidebarMenu = DocCast(doc[field]);
-        const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, scripts, funcs }) => {
+        const menuBtns = CurrentUserUtils.leftSidebarMenuBtnDescriptions(doc).map(({ title, target, icon, toolTip, scripts, funcs }) => {
             const btnDoc = myLeftSidebarMenu ? DocListCast(myLeftSidebarMenu.data).find(doc => doc.title === title) : undefined;
             const reqdBtnOpts:DocumentOptions = {
-                title, icon, target, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List<string>(['height', 'data_columnHeaders']), dontRegisterView: true,
+                title, icon, target, toolTip, btnType: ButtonType.MenuButton, isSystem: true, undoIgnoreFields: new List<string>(['height', 'data_columnHeaders']), dontRegisterView: true,
                 _width: 60, _height: 60,  _dragOnlyWithinContainer: true, _layout_hideContextMenu: true,
             };
             return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdBtnOpts) ?? Docs.Create.FontIconDocument(reqdBtnOpts), scripts, funcs);
@@ -639,7 +639,7 @@ export class CurrentUserUtils {
               btnList: new List<string>(["Roboto", "Roboto Mono", "Nunito", "Times New Roman", "Arial", "Georgia", "Comic Sans MS", "Tahoma", "Impact", "Crimson Text"]) },
             { title: "Font Size",toolTip: "Font size (%size)",    btnType: ButtonType.NumberDropdownButton, width: 75,           toolType:"fontSize", ignoreClick: true,   scripts: {script:  '{ return setFontAttr(self.toolType, value, _readOnly_);}'}, numBtnMax: 200, numBtnMin: 0 },
             { title: "Color",    toolTip: "Font color (%color)",  btnType: ButtonType.ColorButton,  icon: "font",        toolType:"fontColor",ignoreClick: true,   scripts: {script:  '{ return setFontAttr(self.toolType, value, _readOnly_);}'}},
-            { title: "Highlight",toolTip:"Font highlight",       btnType: ButtonType.ColorButton,  icon: "highlighter", toolType:"highlight",ignoreClick: true,   scripts: {script:  '{ return setFontAttr(self.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} },
+            { title: "Highlight",toolTip:"Font highlight",        btnType: ButtonType.ColorButton,  icon: "highlighter", toolType:"highlight",ignoreClick: true,   scripts: {script:  '{ return setFontAttr(self.toolType, value, _readOnly_);}'},funcs: {hidden: "IsNoviceMode()"} },
             { title: "Bold",     toolTip: "Bold (Ctrl+B)",        btnType: ButtonType.ToggleButton, icon: "bold",        toolType:"bold",                          scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
             { title: "Italic",   toolTip: "Italic (Ctrl+I)",      btnType: ButtonType.ToggleButton, icon: "italic",      toolType:"italics",                       scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
             { title: "Under",    toolTip: "Underline (Ctrl+U)",   btnType: ButtonType.ToggleButton, icon: "underline",   toolType:"underline",                     scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
@@ -698,7 +698,7 @@ export class CurrentUserUtils {
             { title: "Header",  icon: "heading",       toolTip: "Header Color",         btnType: ButtonType.ColorButton,         expertMode: false,                                                                                                          ignoreClick: true,             scripts: { script:  'return setHeaderColor(value, _readOnly_)'}},
             { title: "Overlay", icon: "layer-group",   toolTip: "Overlay",              btnType: ButtonType.ToggleButton,        expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'},       scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform
             { title: "Back",    icon: "chevron-left",  toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton,         expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30,  scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
-            { title: "Num", icon:"",toolTip: "Frame Number (click to toggle edit mode)",btnType: ButtonType.TextButton,          expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
+            { title: "Num",     icon:"",                toolTip: "Frame Number (click to toggle edit mode)",    btnType: ButtonType.TextButton,          expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
             { title: "Fwd",     icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton,         expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30,  scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
             { title: "Text",    icon: "Text",          toolTip: "Text functions",       subMenu: CurrentUserUtils.textTools(),   expertMode: false, toolType:DocumentType.RTF,            funcs: {                                                                             linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
             { title: "Ink",     icon: "Ink",           toolTip: "Ink functions",        subMenu: CurrentUserUtils.inkTools(),    expertMode: false, toolType:DocumentType.INK,            funcs: {                                                                             linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index b9f75444f..7d5c38140 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -1,11 +1,12 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { Button, ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, OrientationType, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, OrientationType, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { ColorState, SketchPicker } from 'react-color';
+import * as fa from 'react-icons/fa';
 import { Doc, StrListCast } from '../../../../fields/Doc';
 import { Height, Width } from '../../../../fields/DocSymbols';
 import { InkTool } from '../../../../fields/InkField';
@@ -33,8 +34,6 @@ import { CollectionFreeFormDocumentView } from '../CollectionFreeFormDocumentVie
 import { OpenWhere } from '../DocumentView';
 import { RichTextMenu } from '../formattedText/RichTextMenu';
 import { WebBox } from '../WebBox';
-import { FontIconBadge } from './FontIconBadge';
-import * as fa from 'react-icons/fa'
 import './FontIconBox.scss';
 
 export enum ButtonType {
@@ -316,8 +315,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             .map(value => (
                 {
                     text: value,
-                    shortcut: '#',
-                    icon: <fa.FaCaretUp/>
+                    style: { fontFamily: value }
+                    // shortcut: '#',
                 }
                 // <div
                 //     className="list-item"
@@ -339,7 +338,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             );
 
         return (
-            <Dropdown type={Type.PRIM} dropdownType={DropdownType.CLICK} items={list} location={OrientationType.LEFT}/>
+            <Dropdown color={Colors.WHITE} type={Type.PRIM} dropdownType={DropdownType.SELECT} items={list} location={OrientationType.LEFT}/>
         )
 
         return (
@@ -405,6 +404,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
         const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent';
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
 
         const label =
             !this.label || !FontIconBox.GetShowLabels() ? null : (
@@ -414,12 +414,15 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             );
         
         return (
-            <ColorPicker onChange={(e) => {
-                this.colorPickerClosed = !this.colorPickerClosed;
-                this.noTooltip = !this.colorPickerClosed;
-                setTimeout(() => Doc.UnBrushAllDocs());
-                e.stopPropagation();
-            }}/>
+            <ColorPicker 
+                onChange={(e) => {
+                    this.colorPickerClosed = !this.colorPickerClosed;
+                    setTimeout(() => Doc.UnBrushAllDocs());
+                    e.stopPropagation();
+                }}
+                icon={this.Icon(color)!}
+                tooltip={tooltip}
+            />
         )
 
         return (
@@ -462,40 +465,15 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
         // Determine the type of toggle button
         const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
         const buttonText: string = StrCast(this.rootDoc.buttonText);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
         // Colors
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
 
-        // Button label
-        const label =
-            !this.label || !FontIconBox.GetShowLabels() ? null : (
-                <div className="fontIconBox-label" style={{ color, backgroundColor }}>
-                    {this.label}
-                </div>
-            );
-        console.log("switchToggle", switchToggle, this.rootDoc.title)
+        console.log(buttonText, tooltip);
         return (
-            <Toggle tooltip={this.label} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
+            <Toggle tooltip={`Toggle + ${tooltip}`} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
         )
-
-        if (switchToggle) {
-            return (
-                <div className={`menuButton ${this.type} ${'switch'}`}>
-                    {buttonText ? buttonText : null}
-                    <label className="switch">
-                        <input type="checkbox" checked={backgroundColor === Colors.MEDIUM_BLUE} />
-                        <span className="slider round" />
-                    </label>
-                </div>
-            );
-        } else {
-            return (
-                <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? 'Label' : '')}`} style={{ opacity: 1, backgroundColor, color }}>
-                    {this.Icon(color)}
-                    {label}
-                </div>
-            );
-        }
     }
 
     /**
@@ -504,24 +482,11 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
     @computed get defaultButton() {
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
 
         return (
-            <IconButton icon={this.Icon(color)!} label={this.label}/>
+            <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label}/>
         )
-
-        return (
-            <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu} style={{ backgroundColor: 'transparent', borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
-                <div className="menuButton-wrap">
-                    {this.Icon(color)}
-                    {!this.label || !FontIconBox.GetShowLabels() ? null : (
-                        <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
-                            {' '}
-                            {this.label}{' '}
-                        </div>
-                    )}
-                </div>
-            </div>
-        );
     }
 
     @computed get editableText() {
@@ -544,6 +509,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
     render() {
         const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
         const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
+
         const label = (noBackground: boolean = false) =>
             !this.label || !FontIconBox.GetShowLabels() ? null : (
                 <div className="fontIconBox-label" style={{ color, backgroundColor: noBackground ? 'transparent' : backgroundColor }}>
@@ -577,25 +544,16 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                 break;
             case ButtonType.ClickButton:
             case ButtonType.ToolButton: button = (
-                    <IconButton color={color} icon={this.Icon(color)!} label={this.label}/>
-                    // <div className={`menuButton ${this.type + (FontIconBox.GetShowLabels() ? 'Label' : '')}`} style={{ backgroundColor, color, opacity: 1 }}>
-                    //     {this.Icon(color)}
-                    //     {label()}
-                    // </div>
+                    <IconButton tooltip={tooltip} color={color} icon={this.Icon(color)!} label={this.label}/>
                 );
                 break;
             case ButtonType.MenuButton: button = (
-                    <IconButton size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/>
-                    // <div className={`menuButton ${this.type}`} style={{ color, backgroundColor }}>
-                    //     {this.Icon(color)}
-                    //     {label(true)}
-                    //     <FontIconBadge value={Cast(this.Document.badgeValue, 'string', null)} />
-                    // </div>
+                    <IconButton tooltip={tooltip} size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/>
                 );
                 break;
         }
 
-        return !this.layoutDoc.toolTip || this.noTooltip ? button : <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>{button}</Tooltip>;
+        return button;
     }
 }
 
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index a73d5cce0..80294917f 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -166,13 +166,12 @@ export class TopBar extends React.Component {
     render() {
         return (
             //TODO:glr Add support for light / dark mode
-            <div style={{ pointerEvents: 'all' }} className="topbar-container">
-                <div
-                    className="topbar-inner-container"
-                    style={{
-                        color: this.textColor,
-                        background: this.backgroundColor,
-                    }}>
+            <div style={{ 
+                pointerEvents: 'all',
+                color: this.textColor,
+                background: this.backgroundColor, 
+            }} className="topbar-container">
+                <div className="topbar-inner-container">
                     {this.topbarLeft}
                     {this.topbarCenter}
                     {this.topbarRight}
-- 
cgit v1.2.3-70-g09d2


From de75dacadc556c587bad0006638aab89a21ed7e0 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Mon, 10 Jul 2023 16:15:57 -0400
Subject: updated to v54 of comp library

---
 package-lock.json                             | 6 +++---
 package.json                                  | 2 +-
 src/client/views/nodes/button/FontIconBox.tsx | 8 +++++---
 src/client/views/topbar/TopBar.tsx            | 2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/package-lock.json b/package-lock.json
index 66ac0fca2..bae345949 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6195,9 +6195,9 @@
             }
         },
         "browndash-components": {
-            "version": "0.0.52",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.52.tgz",
-            "integrity": "sha512-rnlHX+h0TQkNLhbS533k4nmPOSyapGHyA7rp0sJw9kzNmjt7Xk75djfimgyoTElU37/k67KKaHnEwaSRro3x3g==",
+            "version": "0.0.54",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.54.tgz",
+            "integrity": "sha512-cwwghwtCtdgbU1eWDH/Ptq03CsQObIjRfK5gcQJsQFS4MrY68ldvTQJnonsuFWJUBXuCIW8I/mBRE92yikYdng==",
             "requires": {
                 "@emotion/react": "^11.11.1",
                 "@emotion/styled": "^11.11.0",
diff --git a/package.json b/package.json
index 45da1e5f4..8ad11054c 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.52",
+        "browndash-components": "0.0.54",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 8314f2d86..d181de8d0 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -1,7 +1,7 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, OrientationType, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { ColorPicker, Dropdown, DropdownType, IconButton, IListItemProps, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -337,7 +337,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
             );
 
         return (
-            <Dropdown selected={{text: text}} color={Colors.WHITE} type={Type.PRIM} dropdownType={DropdownType.SELECT} items={list} location={OrientationType.LEFT}/>
+            <Dropdown selected={{text: text}} color={Colors.WHITE} type={Type.PRIM} dropdownType={DropdownType.SELECT} items={list}/>
         )
 
         return (
@@ -419,6 +419,8 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                     setTimeout(() => Doc.UnBrushAllDocs());
                     e.stopPropagation();
                 }}
+                color={color}
+                type={Type.PRIM}
                 icon={this.Icon(color)!}
                 tooltip={tooltip}
             />
@@ -562,7 +564,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                         // shortcut: '#',
                     }
                 ));
-                button = <Dropdown selected={{text: text}} color={Colors.WHITE} type={Type.PRIM} dropdownType={DropdownType.SELECT} items={list} location={OrientationType.LEFT}/>
+                button = <Dropdown selected={{text: text}} color={Colors.WHITE} type={Type.PRIM} dropdownType={DropdownType.SELECT} items={list}/>
                 break;
             case ButtonType.ColorButton: button = this.colorButton; break;
             case ButtonType.NumberDropdownButton: button = this.numberDropdownButton; break;
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 80294917f..b613a0e3e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -95,7 +95,7 @@ export class TopBar extends React.Component {
             <div className="topbar-center">
                 <Button
                     text={StrCast(Doc.ActiveDashboard.title)}
-                    tooltip="Browsing mode for directly navigating to documents"
+                    tooltip="Open Dashboards"
                     size={Size.SMALL}
                     color={'white'}
                     style={{fontWeight: 700, fontSize: '1rem'}}
-- 
cgit v1.2.3-70-g09d2


From f96fb8dc3e430f93b7a7f3a57fa3fb3d83c813c9 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 13 Jul 2023 20:51:20 -0400
Subject: removed shared dashboards from SharedDocs -- only available through
 the Dashbaord view now.  Need to change hgihlight of Dashboard button to show
 badge w/ new dashboards the same as is done is shard docs.

---
 src/client/documents/Documents.ts                  |  1 +
 src/client/util/CurrentUserUtils.ts                |  9 +++---
 src/client/util/SharingManager.tsx                 | 24 +++++++++++---
 src/client/views/DashboardView.tsx                 | 37 ++++++++++++----------
 src/client/views/StyleProvider.tsx                 |  2 +-
 .../views/collections/CollectionDockingView.tsx    |  4 ---
 src/client/views/nodes/button/FontIconBadge.scss   |  5 +--
 src/client/views/topbar/TopBar.tsx                 |  8 +++--
 8 files changed, 55 insertions(+), 35 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index a39145151..a16742623 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -395,6 +395,7 @@ export class DocumentOptions {
     sidebar_color?: string; // background color of text sidebar
     sidebar_collectionType?: string; // collection type of text sidebar
 
+    data_dashboards?: List<any>; // list of dashboards used in shareddocs;
     text?: string;
     textTransform?: string;
     letterSpacing?: string;
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 0c53caaee..7832b1c87 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -783,11 +783,12 @@ export class CurrentUserUtils {
         const sharedDocOpts:DocumentOptions = {
             title: "My Shared Docs",
             userColor: "rgb(202, 202, 202)",
+            data_dashboards: new List<Doc>(),
             isFolder:true, undoIgnoreFields:new List<string>(['treeViewSortCriterion']),
-            childContextMenuFilters: new List<ScriptField>([dashboardFilter!,]),
-            childContextMenuScripts: new List<ScriptField>([addToDashboards!,]),
-            childContextMenuLabels: new List<string>(["Add to Dashboards",]),
-            childContextMenuIcons: new List<string>(["user-plus",]),
+            // childContextMenuFilters: new List<ScriptField>([dashboardFilter!,]),
+            // childContextMenuScripts: new List<ScriptField>([addToDashboards!,]),
+            // childContextMenuLabels: new List<string>(["Add to Dashboards",]),
+            // childContextMenuIcons: new List<string>(["user-plus",]),
             "acl-Guest": SharingPermissions.Augment, "_acl-Guest": SharingPermissions.Augment,
             childDragAction: "embed", isSystem: true, contentPointerEvents: "all", childLimitHeight: 0, _yMargin: 0, _gridGap: 15, childDontRegisterViews:true,
             // NOTE: treeViewHideTitle & _layout_showTitle is for a TreeView's editable title, _layout_showTitle is for DocumentViews title bar
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 807e812f2..587e1e585 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -49,6 +49,7 @@ const indType = '!indType/';
 const groupType = '!groupType/';
 
 const storage = 'data';
+const dashStorage = 'data_dashboards';
 
 /**
  * A user who also has a sharing doc.
@@ -162,8 +163,9 @@ export class SharingManager extends React.Component<{}> {
         const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.rootDoc);
         docs.map(doc => (this.layoutDocAcls || doc.dockingConfig ? doc : Doc.GetProto(doc))).forEach(doc => {
             distributeAcls(acl, permission as SharingPermissions, doc, undefined, this.overrideNested ? true : undefined);
-            if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc);
-            else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.createdFrom as Doc) || doc);
+            if (permission !== SharingPermissions.None) {
+                Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc);
+            } else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc);
         });
     }, 'set Doc permissions');
 
@@ -186,8 +188,8 @@ export class SharingManager extends React.Component<{}> {
                 this.users
                     .filter(({ user: { email } }) => JSON.parse(StrCast(group.members)).includes(email))
                     .forEach(({ user, sharingDoc }) => {
-                        if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added
-                        else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.createdFrom as Doc) || doc); // remove the doc from the list if it already exists
+                        if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, doc.dockingConfig ? dashStorage : storage, doc); // add the doc to the sharingDoc if it hasn't already been added
+                        else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, ((doc.createdFrom as Doc) || doc).dockingConfig ? dashStorage : storage, (doc.createdFrom as Doc) || doc); // remove the doc from the list if it already exists
                     });
             }
         });
@@ -206,7 +208,13 @@ export class SharingManager extends React.Component<{}> {
             else {
                 DocListCastAsync(user.sharingDoc[storage]).then(userdocs =>
                     DocListCastAsync(group.docsShared).then(dl => {
-                        const filtered = dl?.filter(doc => !userdocs?.includes(doc));
+                        const filtered = dl?.filter(doc => !doc.dockingConfig && !userdocs?.includes(doc));
+                        filtered && userdocs?.push(...filtered);
+                    })
+                );
+                DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
+                    DocListCastAsync(group.docsShared).then(dl => {
+                        const filtered = dl?.filter(doc => doc.dockingConfig && !userdocs?.includes(doc));
                         filtered && userdocs?.push(...filtered);
                     })
                 );
@@ -250,6 +258,12 @@ export class SharingManager extends React.Component<{}> {
                     userdocs?.splice(0, userdocs.length, ...remaining);
                 })
             );
+            DocListCastAsync(user.sharingDoc[dashStorage]).then(userdocs =>
+                DocListCastAsync(group.docsShared).then(dl => {
+                    const remaining = userdocs?.filter(doc => !dl?.includes(doc)) || [];
+                    userdocs?.splice(0, userdocs.length, ...remaining);
+                })
+            );
         }
     };
 
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 0c871b2b2..b8c89d2ff 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -57,7 +57,7 @@ export class DashboardView extends React.Component {
     };
 
     clickDashboard = (e: React.MouseEvent, dashboard: Doc) => {
-        if (this.selectedDashboardGroup === DashboardGroup.SharedDashboards) {   
+        if (this.selectedDashboardGroup === DashboardGroup.SharedDashboards) {
             DashboardView.openSharedDashboard(dashboard);
         } else {
             Doc.ActiveDashboard = dashboard;
@@ -70,17 +70,17 @@ export class DashboardView extends React.Component {
         if (whichGroup === DashboardGroup.MyDashboards) {
             return allDashboards.filter(dashboard => Doc.GetProto(dashboard).author === Doc.CurrentUserEmail);
         }
-        const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc.dockingConfig);
+        const sharedDashboards = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc.dockingConfig);
         return sharedDashboards;
     };
 
     isUnviewedSharedDashboard = (dashboard: Doc): boolean => {
-        // const sharedDashboards = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._type_collection === CollectionViewType.Docking);
+        // const sharedDashboards = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc._type_collection === CollectionViewType.Docking);
         return !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard);
     };
 
     getSharedDashboards = () => {
-        const sharedDashs = DocListCast(Doc.MySharedDocs.data).filter(doc => doc._type_collection === CollectionViewType.Docking);
+        const sharedDashs = DocListCast(Doc.MySharedDocs.data_dashboards).filter(doc => doc._type_collection === CollectionViewType.Docking);
         return sharedDashs.filter(dashboard => !DocListCast(Doc.MySharedDocs.viewed).includes(dashboard));
     };
 
@@ -163,7 +163,13 @@ export class DashboardView extends React.Component {
                             {'My Dashboards (' + this.getDashboards(DashboardGroup.MyDashboards).length + ')'}
                         </div>
                         <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.SharedDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}>
-                            {'Shared Dashboards (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
+                            Shared Dashboards{' '}
+                            <span
+                                style={{
+                                    background: this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'lightgreen' : 'undefined',
+                                }}>
+                                {'(' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
+                            </span>
                         </div>
                     </div>
                     <div className="all-dashboards">
@@ -173,9 +179,11 @@ export class DashboardView extends React.Component {
                                 .filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key))
                                 .some(key => dashboard[DocAcl][key] !== AclPrivate);
                             return (
-                                <div className="dashboard-container" key={dashboard[Id]} //
-                                    style={{ background: shared ? 'lightgreen' : '' }} 
-                                    onContextMenu={e => this.onContextMenu(dashboard, e)} 
+                                <div
+                                    className="dashboard-container"
+                                    key={dashboard[Id]} //
+                                    style={{ background: this.isUnviewedSharedDashboard(dashboard) && this.selectedDashboardGroup === DashboardGroup.SharedDashboards ? 'lightgreen' : shared ? 'lightblue' : '' }}
+                                    onContextMenu={e => this.onContextMenu(dashboard, e)}
                                     onClick={e => this.clickDashboard(e, dashboard)}>
                                     <img
                                         src={
@@ -236,10 +244,10 @@ export class DashboardView extends React.Component {
         return CollectionDockingView.TakeSnapshot(Doc.ActiveDashboard);
     }
 
-    public static openSharedDashboard = (dashboard:Doc) => {
+    public static openSharedDashboard = (dashboard: Doc) => {
         Doc.AddDocToList(Doc.MySharedDocs, 'viewed', dashboard);
         DashboardView.openDashboard(Doc.BestEmbedding(dashboard));
-    }
+    };
 
     /// opens a dashboard as the ActiveDashboard (and adds the dashboard to the users list of dashboards if it's not already there).
     /// this also sets the readonly state of the dashboard based on the current mode of dash (from its url)
@@ -373,8 +381,7 @@ export class DashboardView extends React.Component {
     };
 
     public static createNewDashboard = (id?: string, name?: string, background?: string) => {
-        const dashboards = Doc.MyDashboards;
-        const dashboardCount = DocListCast(dashboards.data).length + 1;
+        const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
@@ -391,7 +398,7 @@ export class DashboardView extends React.Component {
 
         dashboardDoc['pane-count'] = 1;
 
-        Doc.AddDocToList(dashboards, 'data', dashboardDoc);
+        Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
 
         DashboardView.SetupDashboardTrails(dashboardDoc);
 
@@ -453,10 +460,6 @@ export class DashboardView extends React.Component {
     }
 }
 
-export function AddToList(MySharedDocs: Doc, arg1: string, dash: any) {
-    throw new Error('Function not implemented.');
-}
-
 ScriptingGlobals.add(function createNewDashboard() {
     return DashboardView.createNewDashboard();
 }, 'creates a new dashboard when called');
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 9ba0e5e26..f3471c350 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -280,7 +280,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 if (props?.docViewPath().lastElement()?.rootDoc?._type_collection === CollectionViewType.Freeform) {
                     return doc?.pointerEvents !== 'none' ? null : (
                         <div className="styleProvider-lock" onClick={() => toggleLockedPosition(doc)}>
-                            <FontAwesomeIcon icon={'lock'} style={{ color: 'red' }} size="lg" />
+                            <FontAwesomeIcon icon='lock' style={{ color: 'red' }} size="lg" />
                         </div>
                     );
                 }
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index b2eaa964c..8d1b46ebb 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -386,10 +386,6 @@ export class CollectionDockingView extends CollectionSubView() {
                   .map(f => f as Doc);
         const changesMade = this.props.Document.dockingConfig !== json;
         if (changesMade) {
-            if (json.startsWith('{"settings"')) {
-                alert("Porblems looming")
-                debugger;
-            }
             if (![AclAdmin, AclEdit].includes(GetEffectiveAcl(this.dataDoc))) {
                 this.layoutDoc.dockingConfig = json;
                 this.layoutDoc.data = new List<Doc>(docs);
diff --git a/src/client/views/nodes/button/FontIconBadge.scss b/src/client/views/nodes/button/FontIconBadge.scss
index 78f506e57..2ff5c651f 100644
--- a/src/client/views/nodes/button/FontIconBadge.scss
+++ b/src/client/views/nodes/button/FontIconBadge.scss
@@ -1,11 +1,12 @@
 .fontIconBadge {
-    background: red;
+    background: lightgreen;
     width: 15px;
     height: 15px;
     top: 8px;
+    color: black;
     display: block;
     position: absolute;
     right: 5;
     border-radius: 50%;
     text-align: center;
-}
\ No newline at end of file
+}
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 9f2eafcee..0a0bac998 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -5,7 +5,7 @@ import { action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaBug, FaCamera, FaStamp } from 'react-icons/fa';
-import { Doc } from '../../../fields/Doc';
+import { Doc, DocListCast } from '../../../fields/Doc';
 import { AclAdmin } from '../../../fields/DocSymbols';
 import { StrCast } from '../../../fields/Types';
 import { GetEffectiveAcl } from '../../../fields/util';
@@ -59,7 +59,11 @@ export class TopBar extends React.Component {
         return (
             <div className="topbar-left">
                 {Doc.ActiveDashboard ? (
-                    <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.textColor} />
+                    <IconButton
+                        onClick={this.navigateToHome}
+                        icon={<FontAwesomeIcon icon={DocListCast(Doc.MySharedDocs.data_dashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'portrait' : 'home'} />}
+                        color={this.textColor}
+                    />
                 ) : (
                     <div className="logo-container">
                         <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
-- 
cgit v1.2.3-70-g09d2


From 54308259a8cd3ac98aaee550ea01ad97f17172e6 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Mon, 17 Jul 2023 23:11:35 -0400
Subject: so many updates

---
 deploy/index.html                                  |   7 +-
 deploy/loader.css                                  |   5 +-
 package-lock.json                                  | 232 +++----
 package.json                                       |   2 +-
 src/client/documents/Documents.ts                  |   6 +-
 src/client/util/CurrentUserUtils.ts                |  63 +-
 src/client/util/DropConverter.ts                   |   2 +-
 src/client/util/ReportManager.tsx                  |   4 +-
 src/client/util/SettingsManager.scss               |  93 +--
 src/client/util/SettingsManager.tsx                | 186 ++++--
 src/client/views/AntimodeMenu.scss                 |  32 +-
 src/client/views/AntimodeMenu.tsx                  |   5 +
 src/client/views/DashboardView.scss                |  22 +
 src/client/views/DashboardView.tsx                 |  98 ++-
 src/client/views/EditableView.tsx                  |  75 ++-
 src/client/views/GestureOverlay.tsx                |   2 +-
 src/client/views/MainView.scss                     |  20 -
 src/client/views/MainView.tsx                      |  13 +-
 src/client/views/MainViewModal.scss                |   6 +-
 src/client/views/MainViewModal.tsx                 |   7 +-
 src/client/views/PropertiesButtons.scss            |   8 +-
 src/client/views/PropertiesButtons.tsx             |  98 ++-
 .../views/PropertiesDocBacklinksSelector.scss      |   2 +-
 .../views/PropertiesDocBacklinksSelector.tsx       |   2 +-
 src/client/views/PropertiesDocContextSelector.tsx  |   1 +
 src/client/views/PropertiesSection.scss            |  24 +
 src/client/views/PropertiesSection.tsx             |  51 ++
 src/client/views/PropertiesView.scss               | 364 +---------
 src/client/views/PropertiesView.tsx                | 743 ++++++++++-----------
 src/client/views/StyleProvider.tsx                 |  10 +-
 src/client/views/UndoStack.scss                    |   9 +-
 src/client/views/UndoStack.tsx                     |  48 +-
 src/client/views/collections/CollectionMenu.scss   | 651 +-----------------
 src/client/views/collections/CollectionMenu.tsx    |  51 +-
 .../views/collections/CollectionTreeView.tsx       |   2 +
 src/client/views/collections/TabDocView.scss       |  17 -
 src/client/views/collections/TabDocView.tsx        | 103 ++-
 src/client/views/collections/TreeView.scss         |  36 +-
 src/client/views/collections/TreeView.tsx          |  35 +-
 .../collectionFreeForm/MarqueeOptionsMenu.tsx      |  69 +-
 .../collectionLinear/CollectionLinearView.tsx      |  51 +-
 src/client/views/global/globalScripts.ts           |  49 +-
 src/client/views/linking/LinkPopup.scss            |   5 -
 src/client/views/linking/LinkPopup.tsx             |   4 +-
 src/client/views/nodes/DocumentContentsView.tsx    |   2 +-
 src/client/views/nodes/DocumentView.tsx            |   4 +-
 .../views/nodes/FontIconBox/ButtonInterface.ts     |  12 +
 .../views/nodes/FontIconBox/FontIconBadge.scss     |  11 +
 .../views/nodes/FontIconBox/FontIconBadge.tsx      |  37 +
 .../views/nodes/FontIconBox/FontIconBox.scss       | 438 ++++++++++++
 src/client/views/nodes/FontIconBox/FontIconBox.tsx | 412 ++++++++++++
 src/client/views/nodes/button/FontIconBox.scss     | 438 ------------
 src/client/views/nodes/button/FontIconBox.tsx      | 385 -----------
 src/client/views/pdf/AnchorMenu.tsx                | 121 ++--
 src/client/views/search/SearchBox.scss             |   3 +-
 src/client/views/search/SearchBox.tsx              |   7 +-
 src/client/views/selectedDoc/SelectedDocView.scss  |   3 +
 src/client/views/selectedDoc/SelectedDocView.tsx   |  47 ++
 src/client/views/selectedDoc/index.ts              |   1 +
 src/client/views/topbar/TopBar.tsx                 |  36 +-
 60 files changed, 2279 insertions(+), 2991 deletions(-)
 create mode 100644 src/client/views/PropertiesSection.scss
 create mode 100644 src/client/views/PropertiesSection.tsx
 create mode 100644 src/client/views/nodes/FontIconBox/ButtonInterface.ts
 create mode 100644 src/client/views/nodes/FontIconBox/FontIconBadge.scss
 create mode 100644 src/client/views/nodes/FontIconBox/FontIconBadge.tsx
 create mode 100644 src/client/views/nodes/FontIconBox/FontIconBox.scss
 create mode 100644 src/client/views/nodes/FontIconBox/FontIconBox.tsx
 delete mode 100644 src/client/views/nodes/button/FontIconBox.scss
 delete mode 100644 src/client/views/nodes/button/FontIconBox.tsx
 create mode 100644 src/client/views/selectedDoc/SelectedDocView.scss
 create mode 100644 src/client/views/selectedDoc/SelectedDocView.tsx
 create mode 100644 src/client/views/selectedDoc/index.ts

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/deploy/index.html b/deploy/index.html
index f8003f126..c8ad2a8d4 100644
--- a/deploy/index.html
+++ b/deploy/index.html
@@ -5,7 +5,7 @@
     <link rel="preconnect" href="https://fonts.googleapis.com">
     <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
     <link
-        href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&display=swap"
+        href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&family=Lato:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Merriweather:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Roboto:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=Nunito:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;0,1000;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900;1,1000&family=Roboto+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
         rel="stylesheet">
     <link rel="shortcut icon" type="image/jpg" href="./assets/favicon.png" />
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
@@ -67,8 +67,9 @@
         }
 
         .dash-animation-container {
-            width: 10vw;
-            height: 10vw;
+            width: fit-content;
+            height: fit-content;
+            padding: 20px;
             display: flex;
             align-items: center;
             justify-content: center;
diff --git a/deploy/loader.css b/deploy/loader.css
index 4be0cc98c..4d5e04d71 100644
--- a/deploy/loader.css
+++ b/deploy/loader.css
@@ -36,8 +36,9 @@
 }
 
 .dash-animation-container {
-    width: 10vw;
-    height: 10vw;
+    width: fit-content;
+    height: fit-content;
+    padding: 20px;
     display: flex;
     align-items: center;
     justify-content: center;
diff --git a/package-lock.json b/package-lock.json
index 84c1e6219..215468914 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,36 +22,42 @@
             }
         },
         "@babel/compat-data": {
-            "version": "7.22.6",
-            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
-            "integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg=="
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz",
+            "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ=="
         },
         "@babel/core": {
-            "version": "7.22.8",
-            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz",
-            "integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.9.tgz",
+            "integrity": "sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==",
             "requires": {
                 "@ampproject/remapping": "^2.2.0",
                 "@babel/code-frame": "^7.22.5",
-                "@babel/generator": "^7.22.7",
-                "@babel/helper-compilation-targets": "^7.22.6",
-                "@babel/helper-module-transforms": "^7.22.5",
+                "@babel/generator": "^7.22.9",
+                "@babel/helper-compilation-targets": "^7.22.9",
+                "@babel/helper-module-transforms": "^7.22.9",
                 "@babel/helpers": "^7.22.6",
                 "@babel/parser": "^7.22.7",
                 "@babel/template": "^7.22.5",
                 "@babel/traverse": "^7.22.8",
                 "@babel/types": "^7.22.5",
-                "@nicolo-ribaudo/semver-v6": "^6.3.3",
                 "convert-source-map": "^1.7.0",
                 "debug": "^4.1.0",
                 "gensync": "^1.0.0-beta.2",
-                "json5": "^2.2.2"
+                "json5": "^2.2.2",
+                "semver": "^6.3.1"
             },
             "dependencies": {
-                "@nicolo-ribaudo/semver-v6": {
-                    "version": "6.3.3",
-                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
-                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                "@babel/generator": {
+                    "version": "7.22.9",
+                    "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.9.tgz",
+                    "integrity": "sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==",
+                    "requires": {
+                        "@babel/types": "^7.22.5",
+                        "@jridgewell/gen-mapping": "^0.3.2",
+                        "@jridgewell/trace-mapping": "^0.3.17",
+                        "jsesc": "^2.5.1"
+                    }
                 },
                 "debug": {
                     "version": "4.3.4",
@@ -70,6 +76,11 @@
                     "version": "2.1.2",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
                     "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+                },
+                "semver": {
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
                 }
             }
         },
@@ -101,22 +112,17 @@
             }
         },
         "@babel/helper-compilation-targets": {
-            "version": "7.22.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz",
-            "integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz",
+            "integrity": "sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==",
             "requires": {
-                "@babel/compat-data": "^7.22.6",
+                "@babel/compat-data": "^7.22.9",
                 "@babel/helper-validator-option": "^7.22.5",
-                "@nicolo-ribaudo/semver-v6": "^6.3.3",
                 "browserslist": "^4.21.9",
-                "lru-cache": "^5.1.1"
+                "lru-cache": "^5.1.1",
+                "semver": "^6.3.1"
             },
             "dependencies": {
-                "@nicolo-ribaudo/semver-v6": {
-                    "version": "6.3.3",
-                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
-                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
-                },
                 "lru-cache": {
                     "version": "5.1.1",
                     "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -125,6 +131,11 @@
                         "yallist": "^3.0.2"
                     }
                 },
+                "semver": {
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
+                },
                 "yallist": {
                     "version": "3.1.1",
                     "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
@@ -133,19 +144,19 @@
             }
         },
         "@babel/helper-create-class-features-plugin": {
-            "version": "7.22.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.6.tgz",
-            "integrity": "sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz",
+            "integrity": "sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ==",
             "requires": {
                 "@babel/helper-annotate-as-pure": "^7.22.5",
                 "@babel/helper-environment-visitor": "^7.22.5",
                 "@babel/helper-function-name": "^7.22.5",
                 "@babel/helper-member-expression-to-functions": "^7.22.5",
                 "@babel/helper-optimise-call-expression": "^7.22.5",
-                "@babel/helper-replace-supers": "^7.22.5",
+                "@babel/helper-replace-supers": "^7.22.9",
                 "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
                 "@babel/helper-split-export-declaration": "^7.22.6",
-                "@nicolo-ribaudo/semver-v6": "^6.3.3"
+                "semver": "^6.3.1"
             },
             "dependencies": {
                 "@babel/helper-annotate-as-pure": {
@@ -156,21 +167,21 @@
                         "@babel/types": "^7.22.5"
                     }
                 },
-                "@nicolo-ribaudo/semver-v6": {
-                    "version": "6.3.3",
-                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
-                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                "semver": {
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
                 }
             }
         },
         "@babel/helper-create-regexp-features-plugin": {
-            "version": "7.22.6",
-            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.6.tgz",
-            "integrity": "sha512-nBookhLKxAWo/TUCmhnaEJyLz2dekjQvv5SRpE9epWQBcpedWLKt8aZdsuT9XV5ovzR3fENLjRXVT0GsSlGGhA==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz",
+            "integrity": "sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==",
             "requires": {
                 "@babel/helper-annotate-as-pure": "^7.22.5",
-                "@nicolo-ribaudo/semver-v6": "^6.3.3",
-                "regexpu-core": "^5.3.1"
+                "regexpu-core": "^5.3.1",
+                "semver": "^6.3.1"
             },
             "dependencies": {
                 "@babel/helper-annotate-as-pure": {
@@ -181,10 +192,10 @@
                         "@babel/types": "^7.22.5"
                     }
                 },
-                "@nicolo-ribaudo/semver-v6": {
-                    "version": "6.3.3",
-                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
-                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                "semver": {
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
                 }
             }
         },
@@ -264,18 +275,15 @@
             }
         },
         "@babel/helper-module-transforms": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz",
-            "integrity": "sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz",
+            "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==",
             "requires": {
                 "@babel/helper-environment-visitor": "^7.22.5",
                 "@babel/helper-module-imports": "^7.22.5",
                 "@babel/helper-simple-access": "^7.22.5",
-                "@babel/helper-split-export-declaration": "^7.22.5",
-                "@babel/helper-validator-identifier": "^7.22.5",
-                "@babel/template": "^7.22.5",
-                "@babel/traverse": "^7.22.5",
-                "@babel/types": "^7.22.5"
+                "@babel/helper-split-export-declaration": "^7.22.6",
+                "@babel/helper-validator-identifier": "^7.22.5"
             }
         },
         "@babel/helper-optimise-call-expression": {
@@ -292,14 +300,13 @@
             "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ=="
         },
         "@babel/helper-remap-async-to-generator": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz",
-            "integrity": "sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz",
+            "integrity": "sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==",
             "requires": {
                 "@babel/helper-annotate-as-pure": "^7.22.5",
                 "@babel/helper-environment-visitor": "^7.22.5",
-                "@babel/helper-wrap-function": "^7.22.5",
-                "@babel/types": "^7.22.5"
+                "@babel/helper-wrap-function": "^7.22.9"
             },
             "dependencies": {
                 "@babel/helper-annotate-as-pure": {
@@ -313,16 +320,13 @@
             }
         },
         "@babel/helper-replace-supers": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz",
-            "integrity": "sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz",
+            "integrity": "sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==",
             "requires": {
                 "@babel/helper-environment-visitor": "^7.22.5",
                 "@babel/helper-member-expression-to-functions": "^7.22.5",
-                "@babel/helper-optimise-call-expression": "^7.22.5",
-                "@babel/template": "^7.22.5",
-                "@babel/traverse": "^7.22.5",
-                "@babel/types": "^7.22.5"
+                "@babel/helper-optimise-call-expression": "^7.22.5"
             }
         },
         "@babel/helper-simple-access": {
@@ -365,13 +369,12 @@
             "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw=="
         },
         "@babel/helper-wrap-function": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz",
-            "integrity": "sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz",
+            "integrity": "sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q==",
             "requires": {
                 "@babel/helper-function-name": "^7.22.5",
                 "@babel/template": "^7.22.5",
-                "@babel/traverse": "^7.22.5",
                 "@babel/types": "^7.22.5"
             }
         },
@@ -1472,12 +1475,12 @@
             }
         },
         "@babel/plugin-transform-typescript": {
-            "version": "7.22.5",
-            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz",
-            "integrity": "sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz",
+            "integrity": "sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg==",
             "requires": {
                 "@babel/helper-annotate-as-pure": "^7.22.5",
-                "@babel/helper-create-class-features-plugin": "^7.22.5",
+                "@babel/helper-create-class-features-plugin": "^7.22.9",
                 "@babel/helper-plugin-utils": "^7.22.5",
                 "@babel/plugin-syntax-typescript": "^7.22.5"
             },
@@ -1561,12 +1564,12 @@
             }
         },
         "@babel/preset-env": {
-            "version": "7.22.7",
-            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.7.tgz",
-            "integrity": "sha512-1whfDtW+CzhETuzYXfcgZAh8/GFMeEbz0V5dVgya8YeJyCU6Y/P2Gnx4Qb3MylK68Zu9UiwUvbPMPTpFAOJ+sQ==",
+            "version": "7.22.9",
+            "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz",
+            "integrity": "sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g==",
             "requires": {
-                "@babel/compat-data": "^7.22.6",
-                "@babel/helper-compilation-targets": "^7.22.6",
+                "@babel/compat-data": "^7.22.9",
+                "@babel/helper-compilation-targets": "^7.22.9",
                 "@babel/helper-plugin-utils": "^7.22.5",
                 "@babel/helper-validator-option": "^7.22.5",
                 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.5",
@@ -1640,11 +1643,11 @@
                 "@babel/plugin-transform-unicode-sets-regex": "^7.22.5",
                 "@babel/preset-modules": "^0.1.5",
                 "@babel/types": "^7.22.5",
-                "@nicolo-ribaudo/semver-v6": "^6.3.3",
                 "babel-plugin-polyfill-corejs2": "^0.4.4",
                 "babel-plugin-polyfill-corejs3": "^0.8.2",
                 "babel-plugin-polyfill-regenerator": "^0.5.1",
-                "core-js-compat": "^3.31.0"
+                "core-js-compat": "^3.31.0",
+                "semver": "^6.3.1"
             },
             "dependencies": {
                 "@babel/helper-plugin-utils": {
@@ -1652,10 +1655,10 @@
                     "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
                     "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
                 },
-                "@nicolo-ribaudo/semver-v6": {
-                    "version": "6.3.3",
-                    "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
-                    "integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg=="
+                "semver": {
+                    "version": "6.3.1",
+                    "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+                    "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
                 }
             }
         },
@@ -6195,9 +6198,9 @@
             }
         },
         "browndash-components": {
-            "version": "0.0.62",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.62.tgz",
-            "integrity": "sha512-lhIuqOylZF7y4ZQXOdTim2r8Et61AaUROl5UYaooCObHvjJb7WIGpFv9B1RQjlbg8vUJ4jeM3e3qb++Cf6ajPg==",
+            "version": "0.0.76",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.76.tgz",
+            "integrity": "sha512-2ZrDNGxbXnmqRSBifCn6+czz/LqeuyZwSsnRj73Wmo9OOKvYIneGZE17/aFkAl76rXdVmZCcfBdKKBcwEYwNHQ==",
             "requires": {
                 "@emotion/react": "^11.11.1",
                 "@emotion/styled": "^11.11.0",
@@ -6211,9 +6214,9 @@
             },
             "dependencies": {
                 "@babel/cli": {
-                    "version": "7.22.6",
-                    "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.6.tgz",
-                    "integrity": "sha512-Be3/RfEDmkMRGT1+ru5nTkfcvWz5jDOYg1V9rXqTz2u9Qt96O1ryboGvxVBp7wOnYWDB8DNHIWb6DThrpudfOw==",
+                    "version": "7.22.9",
+                    "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.22.9.tgz",
+                    "integrity": "sha512-nb2O7AThqRo7/E53EGiuAkMaRbb7J5Qp3RvN+dmua1U+kydm0oznkhqbTEG15yk26G/C3yL6OdZjzgl+DMXVVA==",
                     "requires": {
                         "@jridgewell/trace-mapping": "^0.3.17",
                         "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3",
@@ -6642,9 +6645,9 @@
                     "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
                 },
                 "postcss": {
-                    "version": "8.4.25",
-                    "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.25.tgz",
-                    "integrity": "sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw==",
+                    "version": "8.4.26",
+                    "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz",
+                    "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==",
                     "requires": {
                         "nanoid": "^3.3.6",
                         "picocolors": "^1.0.0",
@@ -6676,9 +6679,9 @@
                     "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A=="
                 },
                 "styled-components": {
-                    "version": "6.0.3",
-                    "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.3.tgz",
-                    "integrity": "sha512-qEyWvDK4CYCyDckNIruRJIcQSvcUR3dVEw/fwxu1v0LFzUMPr2uf5PhXHp17FkGK+S4TkglOS+XIealo1MssQA==",
+                    "version": "6.0.4",
+                    "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.4.tgz",
+                    "integrity": "sha512-lRJt4vg8hKJhlVG+VKz8QEqPCXKyTryZZ59odyK0UC0HHV3u/mshWTfSay8NpkN0Xijw1iN9r0Leld3dcCcp/w==",
                     "requires": {
                         "@babel/cli": "^7.21.0",
                         "@babel/core": "^7.21.0",
@@ -8156,16 +8159,6 @@
             "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
             "dev": true
         },
-        "d": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
-            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
-            "dev": true,
-            "requires": {
-                "es5-ext": "^0.10.50",
-                "type": "^1.0.1"
-            }
-        },
         "d3": {
             "version": "7.8.4",
             "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz",
@@ -9546,28 +9539,6 @@
                 "is-symbol": "^1.0.2"
             }
         },
-        "es5-ext": {
-            "version": "0.10.62",
-            "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
-            "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
-            "dev": true,
-            "requires": {
-                "es6-iterator": "^2.0.3",
-                "es6-symbol": "^3.1.3",
-                "next-tick": "^1.1.0"
-            }
-        },
-        "es6-iterator": {
-            "version": "2.0.3",
-            "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
-            "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
-            "dev": true,
-            "requires": {
-                "d": "1",
-                "es5-ext": "^0.10.35",
-                "es6-symbol": "^3.1.1"
-            }
-        },
         "es6-promise": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
@@ -9579,7 +9550,6 @@
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
             "dev": true,
             "requires": {
-                "d": "^1.0.1",
                 "ext": "^1.1.2"
             }
         },
@@ -25311,12 +25281,6 @@
             "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
             "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
         },
-        "type": {
-            "version": "1.2.0",
-            "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
-            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
-            "dev": true
-        },
         "type-check": {
             "version": "0.4.0",
             "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
diff --git a/package.json b/package.json
index b137ddd67..e301268dd 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.62",
+        "browndash-components": "0.0.76",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 934803c16..c925cff0f 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -34,7 +34,7 @@ import { ContextMenuProps } from '../views/ContextMenuItem';
 import { DFLT_IMAGE_NATIVE_DIM } from '../views/global/globalCssVariables.scss';
 import { ActiveArrowEnd, ActiveArrowStart, ActiveDash, ActiveFillColor, ActiveInkBezierApprox, ActiveInkColor, ActiveInkWidth, ActiveIsInkMask, InkingStroke } from '../views/InkingStroke';
 import { AudioBox } from '../views/nodes/AudioBox';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
 import { ColorBox } from '../views/nodes/ColorBox';
 import { ComparisonBox } from '../views/nodes/ComparisonBox';
 import { DataVizBox } from '../views/nodes/DataVizBox/DataVizBox';
@@ -324,8 +324,9 @@ export class DocumentOptions {
     badgeValue?: ScriptField;
 
     //LINEAR VIEW
-    linearView_IsExpanded?: BOOLt = new BoolInfo('is linear view expanded');
+    linearView_IsOpen?: BOOLt = new BoolInfo('is linear view open');
     linearView_Expandable?: BOOLt = new BoolInfo('can linear view be expanded');
+    linearView_Dropdown?: BOOLt = new BoolInfo('can linear view be opened as a dropdown');
     linearView_SubMenu?: BOOLt = new BoolInfo('is doc a sub menu of more linear views');
     flexGap?: NUMt = new NumInfo('Linear view flex gap');
     flexDirection?: 'unset' | 'row' | 'column' | 'row-reverse' | 'column-reverse';
@@ -406,6 +407,7 @@ export class DocumentOptions {
 
     clipboard?: Doc;
     hoverBackgroundColor?: string; // background color of a label when hovered
+    userBackgroundColor?: STRt = new StrInfo('background color associated with a Dash user (seen in header fields of shared documents)');
     userColor?: STRt = new StrInfo('color associated with a Dash user (seen in header fields of shared documents)');
 }
 export namespace Docs {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 32229f22f..cde3daf5a 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -12,7 +12,7 @@ import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types";
 import { nullAudio } from "../../fields/URLField";
 import { SetCachedGroups, SharingPermissions } from "../../fields/util";
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
-import { OmitKeys, Utils } from "../../Utils";
+import { OmitKeys, Utils, addStyleSheetRule } from "../../Utils";
 import { DocServer } from "../DocServer";
 import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents";
 import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
@@ -20,7 +20,7 @@ import { TreeViewType } from "../views/collections/CollectionTreeView";
 import { DashboardView } from "../views/DashboardView";
 import { Colors } from "../views/global/globalEnums";
 import { MainView } from "../views/MainView";
-import { ButtonType } from "../views/nodes/button/FontIconBox";
+import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox";
 import { OpenWhere } from "../views/nodes/DocumentView";
 import { OverlayView } from "../views/OverlayView";
 import { DragManager, dropActionType } from "./DragManager";
@@ -28,7 +28,7 @@ import { MakeTemplate } from "./DropConverter";
 import { FollowLinkScript } from "./LinkFollower";
 import { LinkManager } from "./LinkManager";
 import { ScriptingGlobals } from "./ScriptingGlobals";
-import { ColorScheme } from "./SettingsManager";
+import { ColorScheme, SettingsManager } from "./SettingsManager";
 import { UndoManager } from "./UndoManager";
 
 interface Button {
@@ -373,7 +373,7 @@ export class CurrentUserUtils {
         });
 
         const reqdStackOpts:DocumentOptions ={
-            title: "menuItemPanel", childDragAction: "same", backgroundColor: Colors.DARK_GRAY, layout_boxShadow: "rgba(0,0,0,0)",  dontRegisterView: true, ignoreClick: true,
+            title: "menuItemPanel", childDragAction: "same", layout_boxShadow: "rgba(0,0,0,0)",  dontRegisterView: true, ignoreClick: true,
             _chromeHidden: true, _gridGap: 0, _yMargin: 0, _yPadding: 0, _xMargin: 0, _layout_autoHeight: false, _width: 60, _columnWidth: 60, _lockedPosition: true, isSystem: true,
         };
         return DocUtils.AssignDocField(doc, field, (opts, items) => Docs.Create.StackingDocument(items??[], opts), reqdStackOpts, menuBtns, { dropConverter: "convertToButtons(dragData)" });
@@ -609,7 +609,7 @@ export class CurrentUserUtils {
         const btns = btnDescs.map(desc => dockBtn({_width: 30, _height: 30, defaultDoubleClick: 'ignore', undoIgnoreFields: new List<string>(['opacity']), _dragOnlyWithinContainer: true, ...desc.opts}, desc.scripts));
         const dockBtnsReqdOpts:DocumentOptions = {
             title: "docked buttons", _height: 40, flexGap: 0, layout_boxShadow: "standard", childDragAction: 'move',
-            childDontRegisterViews: true, linearView_IsExpanded: true, linearView_Expandable: true, ignoreClick: true
+            childDontRegisterViews: true, linearView_IsOpen: true, linearView_Expandable: true, ignoreClick: true
         };
         reaction(() => UndoManager.redoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Redo")!).opacity = UndoManager.CanRedo() ? 1 : 0.4, { fireImmediately: true });
         reaction(() => UndoManager.undoStack.slice(), () => Doc.GetProto(btns.find(btn => btn.title === "Undo")!).opacity = UndoManager.CanUndo() ? 1 : 0.4, { fireImmediately: true });
@@ -625,12 +625,12 @@ export class CurrentUserUtils {
     }
     static viewTools(): Button[] {
         return [
-            { title: "Snap\xA0Lines", icon: "th",           toolTip: "Show Snap Lines",     btnType: ButtonType.ToggleButton, expertMode: false, toolType:"snaplines",  funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
-            { title: "Grid",          icon: "border-all",   toolTip: "Show Grid",           btnType: ButtonType.ToggleButton, expertMode: false, toolType:"grid",       funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
-            { title: "View\xA0All",   icon: "object-group", toolTip: "Fit all Docs to View",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"viewAll",    funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
-            { title: "Clusters",      icon: "braille",      toolTip: "Show Doc Clusters",   btnType: ButtonType.ToggleButton, expertMode: false, toolType:"clusters",   funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
-            { title: "Cards",         icon: "brain",        toolTip: "Flashcards",          btnType: ButtonType.ToggleButton, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
-            { title: "Arrange",icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange",  btnType: ButtonType.ToggleButton, expertMode: false, toolType:"arrange",    funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: 'showFreeform(self.toolType, _readOnly_)'}}, // Only when floating document is selected in freeform
+            { title: "Snap", icon: "th",           toolTip: "Show Snap Lines",     btnType: ButtonType.ToggleButton, expertMode: false, toolType:"snaplines",  funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+            { title: "Grid",          icon: "border-all",   toolTip: "Show Grid",           btnType: ButtonType.ToggleButton, expertMode: false, toolType:"grid",       funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+            { title: "View All",   icon: "object-group", toolTip: "Fit all Docs to View",btnType: ButtonType.ToggleButton, expertMode: false, toolType:"viewAll",    funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+            { title: "Clusters",      icon: "braille",      toolTip: "Show Doc Clusters",   btnType: ButtonType.ToggleButton, expertMode: false, toolType:"clusters",   funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+            { title: "Cards",         icon: "brain",        toolTip: "Flashcards",          btnType: ButtonType.ToggleButton, expertMode: false, toolType:"flashcards", funcs: {}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
+            { title: "Arrange",icon:"arrow-down-short-wide",toolTip:"Toggle Auto Arrange",  btnType: ButtonType.ToggleButton, expertMode: false, toolType:"arrange",    funcs: {hidden: 'IsNoviceMode()'}, scripts: { onClick: '{ return showFreeform(self.toolType, _readOnly_);}'}}, // Only when floating document is selected in freeform
         ]
     }
     static textTools():Button[] {
@@ -645,9 +645,13 @@ export class CurrentUserUtils {
             { title: "Under",    toolTip: "Underline (Ctrl+U)",   btnType: ButtonType.ToggleButton, icon: "underline",   toolType:"underline",                     scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
             { title: "Bullets",  toolTip: "Bullet List",          btnType: ButtonType.ToggleButton, icon: "list",        toolType:"bullet",                        scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
             { title: "#",        toolTip: "Number List",          btnType: ButtonType.ToggleButton, icon: "list-ol",     toolType:"decimal",                       scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
-            { title: "Left",     toolTip: "Left align (Cmd-[)",   btnType: ButtonType.ToggleButton, icon: "align-left",  toolType:"left",                          scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}' }},
-            { title: "Center",   toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",                        scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
-            { title: "Right",    toolTip: "Right align (Cmd-])",  btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right",                         scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+            { title: "Alignment",toolTip: "Alignment",            btnType: ButtonType.MultiToggleButton,                  toolType:"alignment", ignoreClick: true,  scripts: {script:  '{ return setFontAttr(self.toolType, value, _readOnly_);}'},
+              subMenu: [
+                { title: "Left",     toolTip: "Left align (Cmd-[)",   btnType: ButtonType.ToggleButton, icon: "align-left",  toolType:"left",                          scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}' }},
+                { title: "Center",   toolTip: "Center align (Cmd-\\)",btnType: ButtonType.ToggleButton, icon: "align-center",toolType:"center",                        scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+                { title: "Right",    toolTip: "Right align (Cmd-])",  btnType: ButtonType.ToggleButton, icon: "align-right", toolType:"right",                         scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'} },
+              ]
+            },
             { title: "Dictate",  toolTip: "Dictate",              btnType: ButtonType.ToggleButton, icon: "microphone",  toolType:"dictation",                     scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}},
             { title: "NoLink",   toolTip: "Auto Link",            btnType: ButtonType.ToggleButton, icon: "link",        toolType:"noAutoLink", expertMode:true,   scripts: {onClick: '{ return toggleCharStyle(self.toolType, _readOnly_);}'}, funcs: {hidden: 'IsNoviceMode()'}},
             // { title: "Strikethrough", tooltip: "Strikethrough", btnType: ButtonType.ToggleButton, icon: "strikethrough", scripts: {onClick:: 'toggleStrikethrough()'}},
@@ -695,17 +699,17 @@ export class CurrentUserUtils {
               title: "Perspective",                    toolTip: "View",                 btnType: ButtonType.DropdownList,                                                                                                                                    ignoreClick: true, width: 100, scripts: { script: 'setView(value, _readOnly_)'}},
             { title: "Pin",     icon: "map-pin",       toolTip: "Pin View to Trail",    btnType: ButtonType.ClickButton,         expertMode: false,                                                                                                                             width: 30,  scripts: { onClick: 'pinWithView(altKey)'}},
             { title: "Fill",    icon: "fill-drip",     toolTip: "Background Fill Color",btnType: ButtonType.ColorButton,         expertMode: false,                                                                                                          ignoreClick: true, width: 30,  scripts: { script:  'return setBackgroundColor(value, _readOnly_)'}}, // Only when a document is selected
-            { title: "Header",  icon: "heading",       toolTip: "Header Color",         btnType: ButtonType.ColorButton,         expertMode: false,                                                                                                          ignoreClick: true,             scripts: { script:  'return setHeaderColor(value, _readOnly_)'}},
-            { title: "Overlay", icon: "layer-group",   toolTip: "Overlay",              btnType: ButtonType.ToggleButton,        expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'},       scripts: { onClick: 'toggleOverlay(_readOnly_)'}}, // Only when floating document is selected in freeform
+            { title: "Header",  icon: "heading",       toolTip: "Header Color",         btnType: ButtonType.ColorButton,         expertMode: true,                                                                                                          ignoreClick: true,             scripts: { script:  'return setHeaderColor(value, _readOnly_)'}},
+            { title: "Overlay", icon: "layer-group",   toolTip: "Overlay",              btnType: ButtonType.ToggleButton,        expertMode: true, toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)'},       scripts: { onClick: 'return { toggleOverlay(_readOnly_); }'}}, // Only when floating document is selected in freeform
             { title: "Back",    icon: "chevron-left",  toolTip: "Prev Animation Frame", btnType: ButtonType.ClickButton,         expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30,  scripts: { onClick: 'prevKeyFrame(_readOnly_)'}},
             { title: "Num",     icon:"",               toolTip: "Frame Number (click to toggle edit mode)",    btnType: ButtonType.TextButton,          expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)', buttonText: 'selectedDocs()?.lastElement()?.currentFrame?.toString()'}, width: 20, scripts: { onClick: '{ return curKeyFrame(_readOnly_);}'}},
             { title: "Fwd",     icon: "chevron-right", toolTip: "Next Animation Frame", btnType: ButtonType.ClickButton,         expertMode: true,  toolType:CollectionViewType.Freeform, funcs: {hidden: '!SelectionManager_selectedDocType(self.toolType, self.expertMode)'}, width: 30,  scripts: { onClick: 'nextKeyFrame(_readOnly_)'}},
-            { title: "Text",    icon: "Text",          toolTip: "Text functions",       subMenu: CurrentUserUtils.textTools(),   expertMode: false, toolType:DocumentType.RTF,            funcs: {                                                                             linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
-            { title: "Ink",     icon: "Ink",           toolTip: "Ink functions",        subMenu: CurrentUserUtils.inkTools(),    expertMode: false, toolType:DocumentType.INK,            funcs: {                                                                             linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
-            { title: "Doc",     icon: "Doc",           toolTip: "Freeform Doc tools",   subMenu: CurrentUserUtils.freeTools(),   expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
-            { title: "View",    icon: "View",          toolTip: "View tools",           subMenu: CurrentUserUtils.viewTools(),   expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
-            { title: "Web",     icon: "Web",           toolTip: "Web functions",        subMenu: CurrentUserUtils.webTools(),    expertMode: false, toolType:DocumentType.WEB,            funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected
-            { title: "Schema",  icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema,   funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsExpanded: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected
+            { title: "Text",    icon: "Text",          toolTip: "Text functions",       subMenu: CurrentUserUtils.textTools(),   expertMode: false, toolType:DocumentType.RTF,            funcs: {                                                                             linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+            { title: "Ink",     icon: "Ink",           toolTip: "Ink functions",        subMenu: CurrentUserUtils.inkTools(),    expertMode: false, toolType:DocumentType.INK,            funcs: {                                                                             linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`}, scripts: { onClick: 'setInkToolDefaults()'} }, // Always available
+            { title: "Doc",     icon: "Doc",           toolTip: "Freeform Doc tools",   subMenu: CurrentUserUtils.freeTools(),   expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode, true)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+            { title: "View",    icon: "View",          toolTip: "View tools",           subMenu: CurrentUserUtils.viewTools(),   expertMode: false, toolType:CollectionViewType.Freeform, funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Always available
+            { title: "Web",     icon: "Web",           toolTip: "Web functions",        subMenu: CurrentUserUtils.webTools(),    expertMode: false, toolType:DocumentType.WEB,            funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} }, // Only when Web is selected
+            { title: "Schema",  icon: "Schema",linearBtnWidth:58,toolTip: "Schema functions",subMenu: CurrentUserUtils.schemaTools(), expertMode: false, toolType:CollectionViewType.Schema,   funcs: {hidden: `!SelectionManager_selectedDocType(self.toolType, self.expertMode)`, linearView_IsOpen: `SelectionManager_selectedDocType(self.toolType, self.expertMode)`} } // Only when Schema is selected
         ];
     }
 
@@ -713,7 +717,6 @@ export class CurrentUserUtils {
     static setupContextMenuButton(params:Button, btnDoc?:Doc) {
         const reqdOpts:DocumentOptions = {
             ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit,
-            backgroundColor: params.backgroundColor ??"transparent", ///  a bit hacky. if an onClick is specified, then assume a toggle uses onClick to get the backgroundColor (see below).  Otherwise, assume a transparent background
             color: Colors.WHITE, isSystem: true,
             _nativeWidth: params.width ?? 30, _width: params.width ?? 30,
             _height: 30, _nativeHeight: 30, linearBtnWidth: params.linearBtnWidth,
@@ -722,21 +725,20 @@ export class CurrentUserUtils {
         };
         const reqdFuncs:{[key:string]:any} = {
             ...params.funcs,
-            backgroundColor: params.btnType === ButtonType.ToggleButton ? params.scripts?.onClick:undefined /// a bit hacky.  if onClick is set, then we assume it returns a color value when queried with '_readOnly_'.  This will be true for toggle buttons, but not generally
         }
         return DocUtils.AssignScripts(DocUtils.AssignOpts(btnDoc, reqdOpts) ?? Docs.Create.FontIconDocument(reqdOpts), params.scripts, reqdFuncs);
     }
 
     /// Initializes all the default buttons for the top bar context menu
     static setupContextMenuButtons(doc: Doc, field="myContextMenuBtns") {
-        const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List<string>(['width', "linearView_IsExpanded"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true,  linearView_IsExpanded: true, ignoreClick: true, linearView_Expandable: false, _height: 35 };
+        const reqdCtxtOpts:DocumentOptions = { title: "context menu buttons", undoIgnoreFields:new List<string>(['width', "linearView_IsOpen"]), flexGap: 0, childDragAction: 'embed', childDontRegisterViews: true,  linearView_IsOpen: true, ignoreClick: true, linearView_Expandable: false, _height: 35 };
         const ctxtMenuBtnsDoc = DocUtils.AssignDocField(doc, field, (opts, items) => this.linearButtonList(opts, items??[]), reqdCtxtOpts, undefined);
         const ctxtMenuBtns = CurrentUserUtils.contextMenuTools().map(params => {
             const menuBtnDoc = DocListCast(ctxtMenuBtnsDoc?.data).find(doc => doc.title === params.title);
-            if (!params.subMenu) {
+            if (!params.subMenu) { // button does not have a sub menu
                 return this.setupContextMenuButton(params, menuBtnDoc);
-            } else {
-                const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List<string>(['width', "linearView_IsExpanded"]),
+            } else { // linear view
+                const reqdSubMenuOpts = { ...OmitKeys(params, ["scripts", "funcs", "subMenu"]).omit, undoIgnoreFields: new List<string>(['width', "linearView_IsOpen"]),
                     childDontRegisterViews: true, flexGap: 0, _height: 30, ignoreClick: params.scripts?.onClick ? false : true,
                     linearView_SubMenu: true, linearView_Expandable: true, };
                 const items = params.subMenu?.map(sub =>
@@ -847,6 +849,11 @@ export class CurrentUserUtils {
         doc.fontHighlight ?? (doc.fontHighlight = "");
         doc.defaultAclPrivate ?? (doc.defaultAclPrivate = false);
         doc.savedFilters ?? (doc.savedFilters = new List<Doc>());
+        doc.userBackgroundColor ?? (doc.userBackgroundColor = Colors.DARK_GRAY);
+        addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${doc.userBackgroundColor} !important` });
+        doc.userVariantColor ?? (doc.userVariantColor = Colors.MEDIUM_BLUE);
+        doc.userColor ?? (doc.userColor = Colors.LIGHT_GRAY);
+        doc.userTheme ?? (doc.userTheme = ColorScheme.Dark);
         doc.filterDocCount = 0;
         doc.treeViewFreezeChildren = "remove|add";
         this.setupLinkDocs(doc, linkDatabaseId);
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 47997cc5c..f235be192 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -9,7 +9,7 @@ import { RichTextField } from '../../fields/RichTextField';
 import { ImageField } from '../../fields/URLField';
 import { ScriptingGlobals } from './ScriptingGlobals';
 import { listSpec } from '../../fields/Schema';
-import { ButtonType } from '../views/nodes/button/FontIconBox';
+import { ButtonType } from '../views/nodes/FontIconBox/FontIconBox';
 
 export function MakeTemplate(doc: Doc, first: boolean = true, rename: Opt<string> = undefined, templateField: string = '') {
     if (templateField) Doc.GetProto(doc).title = templateField; /// the title determines which field is being templated
diff --git a/src/client/util/ReportManager.tsx b/src/client/util/ReportManager.tsx
index 4c1020455..89c17e42f 100644
--- a/src/client/util/ReportManager.tsx
+++ b/src/client/util/ReportManager.tsx
@@ -11,7 +11,7 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
 import { DocServer } from '../DocServer';
 import { Networking } from '../Network';
 import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
 import { DragManager } from './DragManager';
 import { GroupManager } from './GroupManager';
 import './SettingsManager.scss';
@@ -290,7 +290,7 @@ export class ReportManager extends React.Component<{}> {
                 isDisplayed={this.isOpen}
                 interactive={true}
                 closeOnExternalClick={this.close}
-                dialogueBoxStyle={{ width: 'auto', height: '500px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }}
+                dialogueBoxStyle={{ width: 'auto', height: '500px', background: Cast(Doc.UserDoc().userColor, 'string', null) }}
             />
         );
     }
diff --git a/src/client/util/SettingsManager.scss b/src/client/util/SettingsManager.scss
index c41adfdd7..bca649bc3 100644
--- a/src/client/util/SettingsManager.scss
+++ b/src/client/util/SettingsManager.scss
@@ -2,41 +2,20 @@
 
 .settings-interface {
     //background-color: whitesmoke !important;
-    color: grey;
     width: 450px;
-
-    button {
-        background: #315a96;
-        outline: none;
-        border-radius: 5px;
-        border: 0px;
-        color: #fcfbf7;
-        text-transform: uppercase;
-        letter-spacing: 2px;
-        font-size: 75%;
-        padding: 10px;
-        margin: 10px;
-        transition: transform 0.2s;
-        margin: 2px;
-    }
 }
 
 .settings-title {
     font-size: 25px;
     font-weight: bold;
     padding-right: 10px;
-    color: black;
 }
 
 .settings-username {
     font-size: 12px;
     padding-right: 15px;
-    color: black;
     margin-top: 10px;
     margin-bottom: 10px;
-    /* right: 135; */
-    // position: absolute;
-    // left: 243;
 }
 
 .settings-section {
@@ -49,7 +28,6 @@
         font-size: 16;
         font-weight: bold;
         text-align: left;
-        color: black;
         width: 80;
         margin-right: 50px;
     }
@@ -61,45 +39,10 @@
 
 .password-content {
     display: flex;
+    width: 100%;
     flex-direction: column;
     align-items: flex-start;
-
-    .password-content-inputs {
-        display: flex;
-        flex-direction: column;
-        width: 100%;
-        font-size: 10px;
-        align-items: flex-start;
-
-        .password-inputs {
-            border: 1px solid rgb(160, 160, 160);
-            margin-bottom: 15px;
-            width: 130;
-            color: $medium-gray;
-            border-radius: 5px;
-            padding: 7px;
-        }
-    }
-
-    .password-content-buttons {
-        display: flex;
-        gap: 5px;
-        justify-content: center;
-        align-items: flex-start;
-        flex-direction: column;
-
-        .password-submit {
-            //margin-left: 85px;
-            margin-top: 5px;
-        }
-
-        .password-forgot {
-            //margin-left: 65px;
-            //margin-top: -20px;
-            font-size: 12px;
-            white-space: nowrap;
-        }
-    }
+    gap: 5px;
 }
 
 .accounts-content {
@@ -115,7 +58,6 @@
         width: 80%;
         height: 35px;
         margin-right: 10px;
-        color: black;
         border-radius: 5px;
 
         &:hover {
@@ -139,12 +81,6 @@
             }
         }
 
-        .playground-text {
-            color: black;
-            margin-right: 10px;
-            margin-top: 2;
-        }
-
         .acl-text {
             color: black;
             margin-top: 2;
@@ -176,7 +112,6 @@
 
 .appearances-content {
     display: flex;
-    color: black;
     font-size: 10px;
 
     .preferences-color {
@@ -201,7 +136,6 @@
         margin-top: 2px;
 
         .preferences-font-text {
-            color: black;
             margin-top: 4;
             margin-right: 4;
             margin-bottom: 2px;
@@ -216,7 +150,6 @@
 
         .font-select {
             height: 35px;
-            color: black;
             font-size: 9;
             margin-right: 6;
             border-radius: 5px;
@@ -229,7 +162,6 @@
 
         .size-select {
             height: 35px;
-            color: black;
             font-size: 9;
             border-radius: 5px;
             width: 30%;
@@ -241,7 +173,6 @@
     }
 
     .preferences-check {
-        color: black;
         margin-right: 4;
         margin-bottom: -3;
         margin-left: 5;
@@ -265,7 +196,6 @@
 
 
     .settings-content {
-        background: #e4e4e4;
         padding: 10px;
         width: 500px;
         flex: 1 1 auto;
@@ -296,7 +226,6 @@
     }
 
     h1 {
-        color: #121721;
         text-transform: uppercase;
         letter-spacing: 2px;
         font-size: 19;
@@ -325,7 +254,6 @@
 
         .padding {
             padding: 0 0 0 20px;
-            color: black;
         }
     }
 }
@@ -336,16 +264,11 @@
     min-height: 250px;
     height: 100%;
     width: 100%;
-
-    .settings-content {
-        background-color: $off-white;
-    }
 }
 
 .settings-panel {
     position: relative;
     min-width: 150px;
-    background-color: $light-blue;
 
     .settings-user {
         position: absolute;
@@ -370,16 +293,11 @@
 .settings-tabs {
     // font-size: 16px;
     font-weight: 600;
-    color: black;
 
     .tab-control {
         padding: 10px;
         border-bottom: 1px solid #9f9e9e;
         cursor: pointer;
-
-        &.active {
-            background-color: #fdfdfd;
-        }
     }
 }
 
@@ -398,16 +316,18 @@
 
 .tab-content {
     display: flex;
+    flex-flow: row wrap;
+    gap: 10px;
+    overflow: hidden;
 
     .tab-column {
-        flex: 0 0 50%;
+        flex: 0 0 calc(50% - 10px);
         flex-direction: column;
         display: flex;
         justify-content: flex-start;
         align-items: flex-start;
 
         .tab-column-title {
-            color: $dark-gray;
             font-size: 16px;
             font-weight: bold;
             margin-bottom: 10px;
@@ -420,6 +340,7 @@
             align-items: flex-start;
             flex-direction: column;
             gap: 10px;
+            width: 100%;
         }
     }
 }
diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx
index 09d6d034f..b6df5f26a 100644
--- a/src/client/util/SettingsManager.tsx
+++ b/src/client/util/SettingsManager.tsx
@@ -11,12 +11,12 @@ import { GoogleAuthenticationManager } from '../apis/GoogleAuthenticationManager
 import { DocServer } from '../DocServer';
 import { Networking } from '../Network';
 import { MainViewModal } from '../views/MainViewModal';
-import { FontIconBox } from '../views/nodes/button/FontIconBox';
+import { FontIconBox } from '../views/nodes/FontIconBox/FontIconBox';
 import { DragManager } from './DragManager';
 import { GroupManager } from './GroupManager';
 import './SettingsManager.scss';
 import { undoBatch } from './UndoManager';
-import { Button, ColorPicker, Dropdown, DropdownType, Group, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { Button, ColorPicker, Dropdown, DropdownType, EditableText, Group, NumberDropdown, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { BsGoogle } from 'react-icons/bs'
 import { FaFillDrip, FaPalette } from 'react-icons/fa'
 const higflyout = require('@hig/flyout');
@@ -24,9 +24,10 @@ export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
 export enum ColorScheme {
-    Dark = '-Dark',
-    Light = '-Light',
-    System = '-MatchSystem',
+    Dark = 'Dark',
+    Light = 'Light',
+    System = 'Match System',
+    Custom = 'Custom'
 }
 
 export enum freeformScrollMode {
@@ -53,8 +54,8 @@ export class SettingsManager extends React.Component<{}> {
     @computed get backgroundColor() {
         return Doc.UserDoc().activeCollectionBackground;
     }
-    @computed get colorScheme() {
-        return Doc.ActiveDashboard?.colorScheme;
+    @computed get userTheme() {
+        return Doc.UserDoc().userTheme;
     }
 
     constructor(props: {}) {
@@ -76,14 +77,31 @@ export class SettingsManager extends React.Component<{}> {
         }
     };
 
+    @computed get userColor() {
+        return StrCast(Doc.UserDoc().userColor)
+    }
+
+    @computed get userVariantColor() {
+        return StrCast(Doc.UserDoc().userVariantColor)
+    }
+
+    @computed get userBackgroundColor() {
+        return StrCast(Doc.UserDoc().userBackgroundColor)
+    }
+
     @undoBatch selectUserMode = action((mode: string) => (Doc.noviceMode = mode === 'Novice'));
     @undoBatch changelayout_showTitle = action((e: React.ChangeEvent) => (Doc.UserDoc().layout_showTitle = (e.currentTarget as any).value ? 'title' : undefined));
     @undoBatch changeFontFamily = action((font: string) => (Doc.UserDoc().fontFamily = font));
     @undoBatch changeFontSize = action((val: number) => (Doc.UserDoc().fontSize = val));
-    @undoBatch switchActiveBackgroundColor = action((color: string) => (Doc.UserDoc().activeCollectionBackground = color));
+    @undoBatch switchUserBackgroundColor = action((color: string) => {
+        Doc.UserDoc().userBackgroundColor = color;
+        addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: `${color} !important` });
+    });
     @undoBatch switchUserColor = action((color: string) => {
-        Doc.SharingDoc().userColor = undefined;
-        Doc.GetProto(Doc.SharingDoc()).userColor = color;
+        Doc.UserDoc().userColor = color;
+    });
+    @undoBatch switchUserVariantColor = action((color: string) => {
+        Doc.UserDoc().userVariantColor = color;
     });
     @undoBatch playgroundModeToggle = action(() => {
         this.playgroundMode = !this.playgroundMode;
@@ -96,22 +114,24 @@ export class SettingsManager extends React.Component<{}> {
     @undoBatch
     @action
     changeColorScheme = action((scheme: string) => {
-        const activeDashboard = Doc.ActiveDashboard;
-        if (!activeDashboard) return;
+        Doc.UserDoc().userTheme = scheme;
         switch (scheme) {
             case ColorScheme.Light:
-                activeDashboard.colorScheme = ColorScheme.Light
-                addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: '#d3d3d3 !important' });
+                this.switchUserColor("#323232")
+                this.switchUserBackgroundColor("#DFDFDF")
+                this.switchUserVariantColor("#BDDDF5")
                 break;
             case ColorScheme.Dark:
-                activeDashboard.colorScheme = ColorScheme.Dark;
-                addStyleSheetRule(SettingsManager._settingsStyle, 'lm_header', { background: 'black !important' });
+                this.switchUserColor("#DFDFDF")
+                this.switchUserBackgroundColor("#323232")
+                this.switchUserVariantColor("#4476F7")
+                break;
+            case ColorScheme.Custom:
                 break;
             case ColorScheme.System:
             default:
-                activeDashboard.colorScheme = ColorScheme.System;
                 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
-                    activeDashboard.colorScheme = e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
+                    e.matches ? ColorScheme.Dark : ColorScheme.Light; // undefined means ColorScheme.Light until all CSS is updated with values for each color scheme (e.g., see MainView.scss, DocumentDecorations.scss)
                 });
                 break;
         }
@@ -120,18 +140,16 @@ export class SettingsManager extends React.Component<{}> {
     @computed get colorsContent() {
 
 
-        const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.System];
-        const schemeMap = ['Light', 'Dark', 'Match System'];
-
+        const colorSchemes = [ColorScheme.Light, ColorScheme.Dark, ColorScheme.Custom, ColorScheme.System];
+        const schemeMap = ['Light', 'Dark', 'Custom', 'Match System'];
+        const userTheme = StrCast(Doc.UserDoc().userTheme);
         return (
-            <div className="colors-content">
-                <ColorPicker formLabel='Background Color' icon={<FaFillDrip/>} selectedColor={StrCast(Doc.UserDoc().activeCollectionBackground)} setSelectedColor={this.switchActiveBackgroundColor}/>
-                <ColorPicker formLabel='User Color' icon={<FaPalette/>} selectedColor={StrCast(Doc.SharingDoc().userColor)} setSelectedColor={this.switchUserColor}/>
+            <div style={{width: '100%'}}>
                 <Dropdown 
                     formLabel='Theme'
                     size={Size.SMALL}
                     type={Type.TERT}
-                    selectedVal={StrCast(Doc.ActiveDashboard?.colorScheme)}
+                    selectedVal={userTheme}
                     setSelectedVal={(scheme) => this.changeColorScheme(scheme as string)}
                     items={colorSchemes.map((scheme, i) => (
                         {
@@ -140,8 +158,14 @@ export class SettingsManager extends React.Component<{}> {
                         }
                     ))} 
                     dropdownType={DropdownType.SELECT}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
+                    fillWidth
                 />
+                {userTheme === ColorScheme.Custom && <Group formLabel='Custom Theme'>
+                    <ColorPicker tooltip={'User Color'} color={this.userColor} type={Type.SEC} icon={<FaFillDrip/>} selectedColor={this.userColor} setSelectedColor={this.switchUserColor}/>
+                    <ColorPicker tooltip={'User Background Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette/>} selectedColor={this.userBackgroundColor} setSelectedColor={this.switchUserBackgroundColor}/>
+                    <ColorPicker tooltip={'User Variant Color'} color={this.userColor} type={Type.SEC} icon={<FaPalette/>} selectedColor={this.userVariantColor} setSelectedColor={this.switchUserVariantColor}/>
+                </Group>}
             </div>
         );
     }
@@ -155,7 +179,7 @@ export class SettingsManager extends React.Component<{}> {
                     toggleType={ToggleType.SWITCH} 
                     onClick={e => (Doc.UserDoc().layout_showTitle = Doc.UserDoc().layout_showTitle ? undefined : 'author_date')} 
                     toggleStatus={Doc.UserDoc().layout_showTitle !== undefined} size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
                 <Toggle 
@@ -165,7 +189,7 @@ export class SettingsManager extends React.Component<{}> {
                     onClick={e => (Doc.UserDoc()['documentLinksButton-fullMenu'] = !Doc.UserDoc()['documentLinksButton-fullMenu'])} 
                     toggleStatus={BoolCast(Doc.UserDoc()['documentLinksButton-fullMenu'])} 
                     size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
                 <Toggle 
@@ -175,7 +199,7 @@ export class SettingsManager extends React.Component<{}> {
                     onClick={e => FontIconBox.SetShowLabels(!FontIconBox.GetShowLabels())} 
                     toggleStatus={FontIconBox.GetShowLabels()} 
                     size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
                 <Toggle 
@@ -185,7 +209,7 @@ export class SettingsManager extends React.Component<{}> {
                     onClick={e => FontIconBox.SetRecognizeGestures(!FontIconBox.GetRecognizeGestures())} 
                     toggleStatus={FontIconBox.GetRecognizeGestures()} 
                     size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
                 <Toggle 
@@ -195,7 +219,7 @@ export class SettingsManager extends React.Component<{}> {
                     onClick={e => (Doc.UserDoc().activeInkHideTextLabels = !Doc.UserDoc().activeInkHideTextLabels)} 
                     toggleStatus={BoolCast(Doc.UserDoc().activeInkHideTextLabels)} 
                     size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
                 <Toggle 
@@ -205,7 +229,7 @@ export class SettingsManager extends React.Component<{}> {
                     onClick={e => (Doc.UserDoc().openInkInLightbox = !Doc.UserDoc().openInkInLightbox)} 
                     toggleStatus={BoolCast(Doc.UserDoc().openInkInLightbox)} 
                     size={Size.XSMALL}
-                    color={StrCast(Doc.SharingDoc().userColor)}
+                    color={this.userColor}
 
                 />
             </div>
@@ -238,6 +262,15 @@ export class SettingsManager extends React.Component<{}> {
                     <div className="tab-column-content">
                         {/* <NumberInput/> */}
                         <Group formLabel={'Default Font'}>
+                            <NumberDropdown 
+                                color={this.userColor} 
+                                numberDropdownType={'input'} 
+                                min={0} max={50} step={2}
+                                type={Type.TERT} 
+                                number={0}
+                                unit={"px"}
+                                setNumber={() => {}}
+                            />
                             <Dropdown 
                                 items={fontFamilies.map((val) => {
                                     return {
@@ -252,7 +285,8 @@ export class SettingsManager extends React.Component<{}> {
                                 type={Type.TERT}
                                 selectedVal={StrCast(Doc.UserDoc().fontFamily)}
                                 setSelectedVal={(val) => {this.changeFontFamily(val as string)}}
-                                color={StrCast(Doc.SharingDoc().userColor)}
+                                color={this.userColor}
+                                fillWidth
                             />
                         </Group>
                     </div>
@@ -262,8 +296,7 @@ export class SettingsManager extends React.Component<{}> {
     }
 
     @action
-    changeVal = (e: React.ChangeEvent, pass: string) => {
-        const value = (e.target as any).value;
+    changeVal = (value: string, pass: string) => {
         switch (pass) {
             case 'curr':
                 this.curr_password = value;
@@ -280,16 +313,33 @@ export class SettingsManager extends React.Component<{}> {
     @computed get passwordContent() {
         return (
             <div className="password-content">
-                <div className="password-content-inputs">
-                    <input className="password-inputs" type="password" placeholder="current password" onChange={e => this.changeVal(e, 'curr')} />
-                    <input className="password-inputs" type="password" placeholder="new password" onChange={e => this.changeVal(e, 'new')} />
-                    <input className="password-inputs" type="password" placeholder="confirm new password" onChange={e => this.changeVal(e, 'conf')} />
-                </div>
-                <div className="password-content-buttons">
-                    {!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
-                    <Button type={Type.SEC} text={'Forgot Password'} color={StrCast(Doc.SharingDoc().userColor)}/>
-                    <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={StrCast(Doc.SharingDoc().userColor)}/>
-                </div>
+                <EditableText placeholder="Current password" 
+                    type={Type.SEC} 
+                    color={this.userColor} 
+                    val={""}
+                    setVal={val => this.changeVal(val as string, 'curr')} 
+                    fillWidth
+                    password
+                />
+                <EditableText placeholder="New password" 
+                    type={Type.SEC} 
+                    color={this.userColor} 
+                    val={""}
+                    setVal={val => this.changeVal(val as string, 'new')} 
+                    fillWidth
+                    password
+                />
+                <EditableText placeholder="Confirm new password" 
+                    type={Type.SEC} 
+                    color={this.userColor} 
+                    val={""}
+                    setVal={val => this.changeVal(val as string, 'conf')} 
+                    fillWidth
+                    password
+                />
+                {!this.passwordResultText ? null : <div className={`${this.passwordResultText.startsWith('Error') ? 'error' : 'success'}-text`}>{this.passwordResultText}</div>}
+                <Button type={Type.SEC} text={'Forgot Password'} color={this.userColor}/>
+                <Button type={Type.TERT} text={'Submit'} onClick={this.changePassword} color={this.userColor}/>
             </div>
         );
     }
@@ -346,14 +396,15 @@ export class SettingsManager extends React.Component<{}> {
                             dropdownType={DropdownType.SELECT}
                             type={Type.TERT}
                             placement='bottom-start'
-                            color={StrCast(Doc.SharingDoc().userColor)}
+                            color={this.userColor}
+                            fillWidth
                         />
                         <Toggle 
                             formLabel={'Playground Mode'} 
                             toggleType={ToggleType.SWITCH} 
                             toggleStatus={this.playgroundMode} 
                             onClick={this.playgroundModeToggle}
-                            color={StrCast(Doc.SharingDoc().userColor)}
+                            color={this.userColor}
                         />
                     </div>
                     <div className="tab-column-title" style={{ marginTop: 20, marginBottom: 10 }}>
@@ -379,7 +430,7 @@ export class SettingsManager extends React.Component<{}> {
                             dropdownType={DropdownType.SELECT}
                             type={Type.TERT}
                             placement='bottom-start'
-                            color={StrCast(Doc.SharingDoc().userColor)}
+                            color={this.userColor}
                         />
                     </div>
                 </div>
@@ -390,12 +441,12 @@ export class SettingsManager extends React.Component<{}> {
                             text={"Manage Groups"}
                             type={Type.TERT}
                             onClick={() => GroupManager.Instance?.open()}
-                            color={StrCast(Doc.SharingDoc().userColor)}
+                            color={this.userColor}
                         />
                         <Toggle 
                             toggleType={ToggleType.SWITCH} 
                             formLabel={"Default access private"}
-                            color={StrCast(Doc.SharingDoc().userColor)}
+                            color={this.userColor}
                             toggleStatus={BoolCast(Doc.defaultAclPrivate)} 
                             onClick={action(() => (Doc.defaultAclPrivate = !Doc.defaultAclPrivate))}/>
                     </div>
@@ -414,23 +465,35 @@ export class SettingsManager extends React.Component<{}> {
             { title: 'Appearance', ele: this.appearanceContent },
             { title: 'Text', ele: this.textContent },
         ];
-
         return (
             <div className="settings-interface">
-                <div className="settings-panel">
+                <div className="settings-panel" style={{ background: this.userColor }}>
                     <div className="settings-tabs">
-                        {tabs.map(tab => (
-                            <div key={tab.title} className={'tab-control ' + (this.activeTab === tab.title ? 'active' : 'inactive')} onClick={action(() => (this.activeTab = tab.title))}>
-                                {tab.title}
-                            </div>
-                        ))}
+                        {tabs.map(tab => {
+                            const isActive = this.activeTab === tab.title
+                            return (
+                                <div key={tab.title}
+                                    style={{
+                                        background: isActive ? this.userBackgroundColor : this.userColor,
+                                        color: isActive ? this.userColor : this.userBackgroundColor,
+                                    }}
+                                    className={'tab-control ' + (isActive ? 'active' : 'inactive')} 
+                                    onClick={action(() => (this.activeTab = tab.title))
+                                }>
+                                    {tab.title}
+                                </div>
+                            )
+                        })}
                     </div>
 
                     <div className="settings-user">
-                        <div className="settings-username">{Doc.CurrentUserEmail}</div>
+                        <div className="settings-username"
+                            style={{color: this.userBackgroundColor}}
+                        >{Doc.CurrentUserEmail}</div>
                         <Button 
                             text={Doc.GuestDashboard ? 'Exit' : 'Log Out'}
                             type={Type.TERT}
+                            color={this.userVariantColor}
                             onClick={() => window.location.assign(Utils.prepend('/logout'))}
                         />
                     </div>
@@ -439,12 +502,13 @@ export class SettingsManager extends React.Component<{}> {
                             
                 <div className="close-button">
                     <Button
-                        icon={<FontAwesomeIcon icon={'times'} color="black" size={'lg'} />}
+                        icon={<FontAwesomeIcon icon={'times'} size={'lg'} />}
                         onClick={this.close}
+                        color={this.userColor}
                     />
                 </div>
 
-                <div className="settings-content">
+                <div className="settings-content" style={{color: this.userColor, background: this.userBackgroundColor}}>
                     {tabs.map(tab => (
                         <div key={tab.title} className={'tab-section ' + (this.activeTab === tab.title ? 'active' : 'inactive')}>
                             {tab.ele}
@@ -462,7 +526,7 @@ export class SettingsManager extends React.Component<{}> {
                 isDisplayed={this.isOpen}
                 interactive={true}
                 closeOnExternalClick={this.close}
-                dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.SharingDoc().userColor, 'string', null) }}
+                dialogueBoxStyle={{ width: 'fit-content', height: '300px', background: Cast(Doc.UserDoc().userColor, 'string', null) }}
             />
         );
     }
diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss
index 8a0e5480e..b205a0f1e 100644
--- a/src/client/views/AntimodeMenu.scss
+++ b/src/client/views/AntimodeMenu.scss
@@ -5,11 +5,15 @@
     position: absolute;
     z-index: 10001;
     height: $antimodemenu-height;
-    background: $dark-gray;
-    border-bottom: $standard-border;
+    width: fit-content;
+    border-radius: $standard-border-radius;
+    overflow: hidden;
     // box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
     // border-radius: 0px 6px 6px 6px;
     display: flex;
+    justify-content: center;
+    align-items: center;
+    gap: 3px;
 
     &.with-rows {
         flex-direction: column
@@ -20,30 +24,6 @@
         height: 35px;
     }
 
-    .antimodeMenu-button {
-        background-color: transparent;
-        width: 35px;
-        height: 35px;
-        padding: 5;
-        text-align: center;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        position: relative;
-
-        .svg {
-            margin: 0;
-        }
-
-        &.active {
-            background-color: #121212;
-        }
-    }
-
-    .antimodeMenu-button:hover {
-        background-color: rgba(0, 0, 0, 0.4);
-    }
-
     .antimodeMenu-dragger {
         height: 100%;
         transition: width .2s;
diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx
index de1207ce4..c41ea7053 100644
--- a/src/client/views/AntimodeMenu.tsx
+++ b/src/client/views/AntimodeMenu.tsx
@@ -1,6 +1,8 @@
 import React = require('react');
 import { observable, action, runInAction } from 'mobx';
 import './AntimodeMenu.scss';
+import { StrCast } from '../../fields/Types';
+import { Doc } from '../../fields/Doc';
 export interface AntimodeMenuProps {}
 
 /**
@@ -148,6 +150,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
                     left: this._left,
                     top: this._top,
                     opacity: this._opacity,
+                    background: StrCast(Doc.UserDoc().userBackgroundColor),
                     transitionProperty: this._transitionProperty,
                     transitionDuration: this._transitionDuration,
                     transitionDelay: this._transitionDelay,
@@ -173,6 +176,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
                     height: 'inherit',
                     width: 200,
                     opacity: this._opacity,
+                    background: StrCast(Doc.UserDoc().userBackgroundColor),
                     transitionProperty: this._transitionProperty,
                     transitionDuration: this._transitionDuration,
                     transitionDelay: this._transitionDelay,
@@ -195,6 +199,7 @@ export abstract class AntimodeMenu<T extends AntimodeMenuProps> extends React.Co
                     left: this._left,
                     top: this._top,
                     opacity: this._opacity,
+                    background: StrCast(Doc.UserDoc().userBackgroundColor),
                     transitionProperty: this._transitionProperty,
                     transitionDuration: this._transitionDuration,
                     transitionDelay: this._transitionDelay,
diff --git a/src/client/views/DashboardView.scss b/src/client/views/DashboardView.scss
index b8a6f6c05..b95312ea0 100644
--- a/src/client/views/DashboardView.scss
+++ b/src/client/views/DashboardView.scss
@@ -14,6 +14,7 @@
             flex-direction: column;
             width: 250px;
             min-width: 250px;
+            gap: 5px;
       }
 
       .all-dashboards {
@@ -56,15 +57,26 @@
     display: flex;
     justify-content: center;
     align-items: center;
+    position: relative;
 
     &:hover {
         color: $light-blue;
         border: solid 2px $light-blue;
     }
+
+    .background {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        left: 0;
+        top: 0;
+        z-index: -1;
+      }
 }
 
 .dashboard-container {
       border-radius: 10px;
+      position: relative;
       cursor: pointer;
       width: 250px;
       height: 200px;
@@ -99,10 +111,20 @@
       .more {
             z-index: 100;
       }
+
+      .background {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        left: 0;
+        top: 0;
+        z-index: -1;
+      }
 }
 
 .new-dashboard {
     color: $dark-gray;
+    padding: 10px;
     display: flex;
     width: 100%;
     height: 100%;
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 3bd6ac61c..dd1079d88 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, FontSize, IconButton, Size, Type } from 'browndash-components';
+import { Button, ColorPicker, EditableText, FontSize, IconButton, Size, Type } from 'browndash-components';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
@@ -24,7 +24,7 @@ import { ContextMenu } from './ContextMenu';
 import './DashboardView.scss';
 import { Colors } from './global/globalEnums';
 import { MainViewModal } from './MainViewModal';
-import { ButtonType } from './nodes/button/FontIconBox';
+import { ButtonType } from './nodes/FontIconBox/FontIconBox';
 import { FaPlus } from 'react-icons/fa';
 
 enum DashboardGroup {
@@ -43,13 +43,16 @@ export class DashboardView extends React.Component {
     @observable private selectedDashboardGroup = DashboardGroup.MyDashboards;
 
     @observable private newDashboardName: string | undefined = undefined;
-    @observable private newDashboardColor: string | undefined = undefined;
+    @observable private newDashboardColor: string | undefined = "#AFAFAF";
     @action abortCreateNewDashboard = () => {
         this.newDashboardName = undefined;
     };
     @action setNewDashboardName(name: string) {
         this.newDashboardName = name;
     }
+    @action setNewDashboardColor(color: string) {
+        this.newDashboardColor = color;
+    }
 
     @action
     selectDashboardGroup = (group: DashboardGroup) => {
@@ -95,23 +98,33 @@ export class DashboardView extends React.Component {
         const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
         const placeholder = `Dashboard ${dashboardCount}`;
         return (
-            <div className="new-dashboard">
+            <div className="new-dashboard"
+                style={{ 
+                    background: StrCast(Doc.UserDoc().userBackgroundColor),
+                    color: StrCast(Doc.UserDoc().userColor)
+                }}
+            >
                 <div className="header">Create New Dashboard</div>
-                <div className="title-input">
-                    Title
-                    <input className="input" placeholder={placeholder} onChange={e => this.setNewDashboardName((e.target as any).value)} />
-                </div>
-                <div className="color-picker">
-                    Background
-                    <ColorPicker
-                        onChange={color => {
-                            this.newDashboardColor = color;
-                        }}
-                    />
-                </div>
+                <EditableText 
+                    formLabel='Title'
+                    placeholder={placeholder}
+                    type={Type.SEC}
+                    color={StrCast(Doc.UserDoc().userColor)}
+                    setVal={val => this.setNewDashboardName(val as string)}
+                    fillWidth
+                />
+                <ColorPicker
+                    formLabel='Background'
+                    colorPickerType='github'
+                    type={Type.TERT}
+                    selectedColor={this.newDashboardColor}
+                    setSelectedColor={color => {
+                        this.setNewDashboardColor(color);
+                    }}
+                />
                 <div className="button-bar">
-                    <Button text="Cancel" onClick={this.abortCreateNewDashboard} />
-                    <Button text="Create" onClick={() => this.createNewDashboard(this.newDashboardName!, this.newDashboardColor)} />
+                    <Button text="Cancel" color={StrCast(Doc.UserDoc().userColor)} onClick={this.abortCreateNewDashboard} />
+                    <Button type={Type.TERT} text="Create" color={StrCast(Doc.UserDoc().userVariantColor)} onClick={() => this.createNewDashboard(this.newDashboardName!, this.newDashboardColor)} />
                 </div>
             </div>
         );
@@ -150,32 +163,49 @@ export class DashboardView extends React.Component {
     };
 
     render() {
+        const color = StrCast(Doc.UserDoc().userColor)
+        const variant = StrCast(Doc.UserDoc().userVariantColor)
         return (
             <>
                 <div className="dashboard-view">
                     <div className="left-menu">
-                        <div className="new-dashboard-button">
-                            <Button icon={<FaPlus />} size={Size.LARGE} text="New" type={Type.SEC} onClick={() => this.setNewDashboardName('')} />
-                        </div>
-                        <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.MyDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)}>
-                            My Dashboards
-                        </div>
-                        <div className={`text-button ${this.selectedDashboardGroup === DashboardGroup.SharedDashboards && 'selected'}`} onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}>
-                            Shared Dashboards
-                        </div>
+                        <Button 
+                            text={'My Dashboards'}
+                            active={this.selectedDashboardGroup === DashboardGroup.MyDashboards}
+                            color={color}
+                            align={'flex-start'}
+                            onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)}
+                            fillWidth
+                        />
+                        <Button 
+                            text={'Shared Dashboards'}
+                            active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
+                            color={color}
+                            align={'flex-start'}
+                            onClick={() => this.selectDashboardGroup(DashboardGroup.SharedDashboards)}
+                            fillWidth
+                        />
+                        <Button icon={<FaPlus />} color={variant} iconPlacement="left" text="New Dashboard" type={Type.TERT} onClick={() => this.setNewDashboardName('')} />
                     </div>
                     <div className="all-dashboards">
                         {this.getDashboards().map(dashboard => {
                             const href = ImageCast(dashboard.thumb)?.url.href;
                             return (
-                                <div className="dashboard-container" key={dashboard[Id]} onContextMenu={e => this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}>
+                                <div 
+                                    className="dashboard-container" key={dashboard[Id]} 
+                                    onContextMenu={e => this.onContextMenu(dashboard, e)} onClick={e => this.clickDashboard(e, dashboard)}>
                                     <img
                                         src={
                                             href ?? 'https://media.istockphoto.com/photos/hot-air-balloons-flying-over-the-botan-canyon-in-turkey-picture-id1297349747?b=1&k=20&m=1297349747&s=170667a&w=0&h=oH31fJty_4xWl_JQ4OIQWZKP8C6ji9Mz7L4XmEnbqRU='
                                         }
                                     />
                                     <div className="info">
-                                        <input style={{ border: 'unset' }} className="input" onClick={e => e.stopPropagation()} defaultValue={StrCast(dashboard.title)} onChange={e => (Doc.GetProto(dashboard).title = (e.target as any).value)} />
+                                        <EditableText 
+                                            type={Type.PRIM}
+                                            color={color}
+                                            val={StrCast(dashboard.title)} 
+                                            setVal={val => (Doc.GetProto(dashboard).title = val)}
+                                        />
                                         {this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? <div>unviewed</div> : <div></div>}
                                         <div
                                             className="more"
@@ -188,9 +218,13 @@ export class DashboardView extends React.Component {
                                                 e.stopPropagation();
                                                 this.onContextMenu(dashboard, e);
                                             }}>
-                                            <Button size={Size.SMALL} icon={<FontAwesomeIcon color="black" size="lg" icon="bars" />} />
+                                            <Button size={Size.SMALL} color={color} icon={<FontAwesomeIcon color={color} size="lg" icon="bars" />} />
                                         </div>
                                     </div>
+                                    <div className={`background`} style={{
+                                        background: StrCast(Doc.UserDoc().userColor),
+                                        filter: 'opacity(0.2)'
+                                    }}/>
                                 </div>
                             );
                         })}
@@ -200,6 +234,10 @@ export class DashboardView extends React.Component {
                                 this.setNewDashboardName('');
                             }}>
                             +
+                            <div className={`background`} style={{
+                                background: StrCast(Doc.UserDoc().userColor),
+                                filter: 'opacity(0.2)'
+                            }}/>
                         </div>
                     </div>
                 </div>
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 7043edcee..4deed5ed9 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -6,6 +6,7 @@ import { ObjectField } from '../../fields/ObjectField';
 import './EditableView.scss';
 import { DocumentIconContainer } from './nodes/DocumentIcon';
 import { OverlayView } from './OverlayView';
+import { EditableText } from 'browndash-components';
 
 export interface EditableProps {
     /**
@@ -231,39 +232,49 @@ export class EditableView extends React.Component<EditableProps> {
                     onChange: this.props.autosuggestProps.onChange,
                 }}
             />
-        ) : this.props.oneLine !== false && this.props.GetValue()?.toString().indexOf('\n') === -1 ? (
-            <input
-                className="editableView-input"
-                ref={r => (this._inputref = r)}
-                style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
-                placeholder={this.props.placeholder}
-                onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
-                defaultValue={this.props.GetValue()}
-                autoFocus={true}
-                onChange={this.onChange}
-                onKeyDown={this.onKeyDown}
-                onKeyPress={this.stopPropagation}
-                onPointerDown={this.stopPropagation}
-                onClick={this.stopPropagation}
-                onPointerUp={this.stopPropagation}
+        ) : <EditableText
+                // oneLine={this.props.oneLine && this.props.GetValue()?.toString().indexOf('\n') === -1}
+                editing={true} 
+                onEdit={function (newText: string): void {
+                    throw new Error('Function not implemented.');
+                } } 
+                setEditing={function (editing: boolean): void {
+                    throw new Error('Function not implemented.');
+                } }                
+                // onEdit={this.onChange}
             />
-        ) : (
-            <textarea
-                className="editableView-input"
-                ref={r => (this._inputref = r)}
-                style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minHeight: `min(100%, ${(this.props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this.props.background }}
-                placeholder={this.props.placeholder}
-                onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
-                defaultValue={this.props.GetValue()}
-                autoFocus={true}
-                onChange={this.onChange}
-                onKeyDown={this.onKeyDown}
-                onKeyPress={this.stopPropagation}
-                onPointerDown={this.stopPropagation}
-                onClick={this.stopPropagation}
-                onPointerUp={this.stopPropagation}
-            />
-        );
+        //     // <input
+        //     //     className="editableView-input"
+        //     //     ref={r => (this._inputref = r)}
+        //     //     style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minWidth: 20, background: this.props.background }}
+        //     //     placeholder={this.props.placeholder}
+        //     //     onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
+        //     //     defaultValue={this.props.GetValue()}
+        //     //     autoFocus={true}
+        //     //     onChange={this.onChange}
+        //     //     onKeyDown={this.onKeyDown}
+        //     //     onKeyPress={this.stopPropagation}
+        //     //     onPointerDown={this.stopPropagation}
+        //     //     onClick={this.stopPropagation}
+        //     //     onPointerUp={this.stopPropagation}
+        //     // />
+        // ) : (
+        //     <textarea
+        //         className="editableView-input"
+        //         ref={r => (this._inputref = r)}
+        //         style={{ display: this.props.display, overflow: 'auto', fontSize: this.props.fontSize, minHeight: `min(100%, ${(this.props.GetValue()?.split('\n').length || 1) * 15})`, minWidth: 20, background: this.props.background }}
+        //         placeholder={this.props.placeholder}
+        //         onBlur={e => this.finalizeEdit(e.currentTarget.value, false, true, false)}
+        //         defaultValue={this.props.GetValue()}
+        //         autoFocus={true}
+        //         onChange={this.onChange}
+        //         onKeyDown={this.onKeyDown}
+        //         onKeyPress={this.stopPropagation}
+        //         onPointerDown={this.stopPropagation}
+        //         onClick={this.stopPropagation}
+        //         onPointerUp={this.stopPropagation}
+        //     />
+        // );
     }
 
     render() {
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 54ad519de..4e6d5c2e9 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -31,7 +31,7 @@ import {
     SetActiveInkWidth,
 } from './InkingStroke';
 import { InkTranscription } from './InkTranscription';
-import { checkInksToGroup } from './nodes/button/FontIconBox';
+import { checkInksToGroup } from './nodes/FontIconBox/FontIconBox';
 import { DocumentView } from './nodes/DocumentView';
 import { RadialMenu } from './nodes/RadialMenu';
 import { Touchable } from './Touchable';
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index b95ce0e99..e33054c8e 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -68,10 +68,6 @@ h1,
     left: 0;
     z-index: 1;
     touch-action: none;
-
-    .searchBox-container {
-        background: $light-gray;
-    }
 }
 
 .mainView-container,
@@ -118,10 +114,6 @@ h1,
         background: $light-gray;
     }
 
-    .searchBox-container {
-        background: $dark-gray;
-    }
-
     .contextMenu-cont,
     .contextMenu-item {
         background: $dark-gray;
@@ -193,17 +185,6 @@ h1,
             background: $light-gray;
         }
     }
-
-    .propertiesView {
-        left: 0;
-        position: absolute;
-        z-index: 2;
-        background-color: $light-gray;
-
-        .editable-title {
-            background-color: $light-gray;
-        }
-    }
 }
 
 .mainView-libraryHandle {
@@ -250,7 +231,6 @@ h1,
 
 .mainView-leftMenuPanel {
     min-width: var(--menuPanelWidth);
-    background-color: $dark-gray;
     border-right: $standard-border;
 
     .collectionStackingView {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index ec8f5989f..a7164f88b 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -754,7 +754,8 @@ export class MainView extends React.Component {
 
     @computed get leftMenuPanel() {
         return (
-            <div key="menu" className="mainView-leftMenuPanel" style={{ display: LightboxView.LightboxDoc ? 'none' : undefined }}>
+            <div key="menu" className="mainView-leftMenuPanel" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor),
+                display: LightboxView.LightboxDoc ? 'none' : undefined }}>
                 <DocumentView
                     Document={Doc.MyLeftSidebarMenu}
                     DataDoc={undefined}
@@ -809,8 +810,8 @@ export class MainView extends React.Component {
                 {this._hideUI ? null : this.leftMenuPanel}
                 <div key="inner" className={`mainView-innerContent${this.colorScheme}`}>
                     {this.flyout}
-                    <div className="mainView-libraryHandle" style={{ left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}>
-                        <FontAwesomeIcon icon="chevron-left" color={this.colorScheme === ColorScheme.Dark ? 'white' : 'black'} style={{ opacity: '50%' }} size="sm" />
+                    <div className="mainView-libraryHandle" style={{ background: StrCast(Doc.UserDoc().userBackgroundColor), left: leftMenuFlyoutWidth - 10 /* ~half width of handle */, display: !this._leftMenuFlyoutWidth ? 'none' : undefined }} onPointerDown={this.onFlyoutPointerDown}>
+                        <FontAwesomeIcon icon="chevron-left" color={StrCast(Doc.UserDoc().userColor)} style={{ opacity: '50%' }} size="sm" />
                     </div>
                     <div className="mainView-innerContainer" style={{ width: `calc(100% - ${width}px)` }}>
                         {this.dockingContent}
@@ -964,7 +965,11 @@ export class MainView extends React.Component {
     render() {
         return (
             <div
-                className={`mainView-container${this.colorScheme}`}
+                className={`mainView-container ${this.colorScheme}`}
+                style={{
+                    color: StrCast(Doc.UserDoc().userColor),
+                    background: StrCast(Doc.UserDoc().userBackgroundColor),
+                }}
                 onScroll={() => (ele => (ele.scrollTop = ele.scrollLeft = 0))(document.getElementById('root')!)}
                 ref={r => {
                     r &&
diff --git a/src/client/views/MainViewModal.scss b/src/client/views/MainViewModal.scss
index 0648e31c5..4bf9eb79f 100644
--- a/src/client/views/MainViewModal.scss
+++ b/src/client/views/MainViewModal.scss
@@ -4,22 +4,23 @@
     z-index: 10000;
     width: 100%;
     height: 100%;
+    box-shadow: #00000044 5px 5px 10px;
 
     .dialogue-box {
-        padding: 10px;
         position: absolute;
         z-index: 1000;
         text-align: center;
         justify-content: center;
         align-self: center;
         align-content: center;
-        background: white;
         // border-radius: 10px;
         box-shadow: #00000044 5px 5px 10px;
         transform: translate(-50%, -50%);
         top: 50%;
         left: 50%;
         transition: 0.5s all ease;
+        border-radius: 10px;
+        overflow: hidden;
     }
 
     .overlay {
@@ -28,6 +29,7 @@
         position: absolute;
         z-index: 999;
         transition: 0.5s all ease;
+        backdrop-filter: blur(5px);
     }
 
 }
\ No newline at end of file
diff --git a/src/client/views/MainViewModal.tsx b/src/client/views/MainViewModal.tsx
index 32997a944..42df99864 100644
--- a/src/client/views/MainViewModal.tsx
+++ b/src/client/views/MainViewModal.tsx
@@ -1,6 +1,10 @@
 import * as React from 'react';
 import './MainViewModal.scss';
 import { observer } from 'mobx-react';
+import { Doc } from '../../fields/Doc';
+import { StrCast } from '../../fields/Types';
+import { isDark } from 'browndash-components';
+import { Colors } from './global/globalEnums';
 
 export interface MainViewOverlayProps {
     isDisplayed: boolean;
@@ -41,9 +45,8 @@ export class MainViewModal extends React.Component<MainViewOverlayProps> {
                     className="overlay"
                     onClick={this.props?.closeOnExternalClick}
                     style={{
-                        backgroundColor: 'black',
+                        backgroundColor: isDark(StrCast(Doc.UserDoc().userColor)) ? "#DFDFDF30" : "#32323230",
                         ...(p.overlayStyle || {}),
-                        opacity: p.isDisplayed ? overlayOpacity : 0,
                     }}
                 />
             </div>
diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index 36b2df73e..db30745fc 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -57,14 +57,13 @@ $linkGap : 3px;
 }
 
 .propertiesButtons {
-    margin-top: 3px;
-    grid-column: 1/4;
     width: 100%;
     height: auto;
     display: flex;
     flex-direction: row;
     flex-wrap: wrap;
     padding-bottom: 5.5px;
+    gap: 5px;
 }
 
 .onClickFlyout-editScript {
@@ -81,10 +80,7 @@ $linkGap : 3px;
 .propertiesButtons-button {
     pointer-events: auto;
     padding-right: 5px;
-    width: 25px;
-    border-radius: 5px;
-    margin-right: 20px;
-    margin-bottom: 8px;
+    width: 100%;
 }
 
 .propertiesButton-dropdownList {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 74dd1c2f7..3148d9ddd 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -21,6 +21,7 @@ import { DocumentView, OpenWhere } from './nodes/DocumentView';
 import { pasteImageBitmap } from './nodes/WebBoxRenderer';
 import './PropertiesButtons.scss';
 import React = require('react');
+import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components';
 const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -44,24 +45,23 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     propertyToggleBtn = (label: string, property: string, tooltip: (on?: any) => string, icon: (on: boolean) => string, onClick?: (dv: Opt<DocumentView>, doc: Doc, property: string) => void, useUserDoc?: boolean) => {
         const targetDoc = useUserDoc ? Doc.UserDoc() : this.selectedDoc;
         const onPropToggle = (dv: Opt<DocumentView>, doc: Doc, prop: string) => ((dv?.layoutDoc || doc)[prop] = (dv?.layoutDoc || doc)[prop] ? false : true);
-        return !targetDoc ? null : (
-            <Tooltip title={<div className={`dash-tooltip`}>{tooltip(targetDoc?.[property])} </div>} placement="top">
-                <div>
-                    <div
-                        className={`propertiesButtons-linkButton-empty toggle-${StrCast(targetDoc[property]).includes(':hover') ? 'hover' : targetDoc[property] ? 'on' : 'off'}`}
-                        onPointerDown={e => e.stopPropagation()}
-                        onClick={undoable(() => {
-                            if (SelectionManager.Views().length > 1) {
-                                SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property));
-                            } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
-                        }, property)}>
-                        <FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} />
-                    </div>
-                    <div className="propertiesButtons-title">{label}</div>
-                </div>
-            </Tooltip>
-        );
+        return !targetDoc ? null : <Toggle
+            toggleStatus={BoolCast(targetDoc[property])}
+            text={tooltip(targetDoc?.[property])}
+            color={StrCast(Doc.UserDoc().userColor)}
+            icon={<FontAwesomeIcon className="documentdecorations-icon" size="lg" icon={icon(BoolCast(targetDoc?.[property])) as any} />}
+            iconPlacement={'left'}
+            align={'flex-start'}
+            fillWidth={true}
+            toggleType={ToggleType.BUTTON}
+            onClick={undoable(() => {
+                if (SelectionManager.Views().length > 1) {
+                    SelectionManager.Views().forEach(dv => (onClick ?? onPropToggle)(dv, dv.rootDoc, property));
+                } else if (targetDoc) (onClick ?? onPropToggle)(undefined, targetDoc, property);
+            }, property)}
+        />
     };
+
     @computed get lockButton() {
         return this.propertyToggleBtn(
             'No\xA0Drag',
@@ -244,21 +244,61 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         );
     }
 
+    @computed get onClickVal() {
+        const linkButton = IsFollowLinkScript(this.selectedDoc.onClick);
+        const followLoc = this.selectedDoc._followLinkLocation;
+        const linkedToLightboxView = () => LinkManager.Links(this.selectedDoc).some(link => LinkManager.getOppositeAnchor(link, this.selectedDoc)?._isLightbox);
+
+        if (followLoc === OpenWhere.lightbox && !linkedToLightboxView()) return 'linkInPlace'
+        else if (linkButton && followLoc === OpenWhere.addRight) return 'linkOnRight'
+        else if (linkButton && this.selectedDoc._followLinkLocation === OpenWhere.lightbox && linkedToLightboxView()) return 'enterPortal'
+        else if (ScriptCast(this.selectedDoc.onClick)?.script.originalScript.includes('toggleDetail')) return 'toggleDetail'
+        else return 'nothing'
+    }
+
     @computed
     get onClickButton() {
+        const buttonList = [
+            ['nothing', 'Select Document'],
+            ['enterPortal', 'Enter Portal'],
+            ['toggleDetail', 'Toggle Detail'],
+            ['linkInPlace', 'Open Link in Lightbox'],
+            ['linkOnRight', 'Open Link on Right'],
+        ];
+        
+        const items: IListItemProps[] = buttonList.map(value => {
+            return (
+                {
+                    text: value[1],
+                    val: value[1],
+                }
+            );
+        });
+        console.log("click val: ", this.onClickVal)
         return !this.selectedDoc ? null : (
-            <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top">
-                <div>
-                    <div className="propertiesButtons-linkFlyout">
-                        <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}>
-                            <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}>
-                                <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" />
-                            </div>
-                        </Flyout>
-                    </div>
-                    <div className="propertiesButtons-title"> onclick </div>
-                </div>
-            </Tooltip>
+            <Dropdown
+                tooltip={'Choose onClick behavior'} 
+                items={items}
+                selectedVal={this.onClickVal}
+                setSelectedVal={(val) => this.handleOptionChange(val as string)}
+                title={'Choose onClick behaviour'}
+                color={StrCast(Doc.UserDoc().userColor)}
+                dropdownType={DropdownType.SELECT}
+                type={Type.SEC}
+                fillWidth
+            />
+            // <Tooltip title={<div className="dash-tooltip">Choose onClick behavior</div>} placement="top">
+            //     <div>
+            //         <div className="propertiesButtons-linkFlyout">
+            //             <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onClickFlyout}>
+            //                 <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}>
+            //                     <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" />
+            //                 </div>
+            //             </Flyout>
+            //         </div>
+            //         <div className="propertiesButtons-title"> onclick </div>
+            //     </div>
+            // </Tooltip>
         );
     }
     @computed
diff --git a/src/client/views/PropertiesDocBacklinksSelector.scss b/src/client/views/PropertiesDocBacklinksSelector.scss
index 4d2a61c3b..5c53acf48 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.scss
+++ b/src/client/views/PropertiesDocBacklinksSelector.scss
@@ -1,4 +1,4 @@
-.propertiesView-contexts-content {
+.propertiesDocBacklinksSelector {
     .linkMenu {
         position: relative;
     }
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index 3e69bcba6..da4438481 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -31,7 +31,7 @@ export class PropertiesDocBacklinksSelector extends React.Component<PropertiesDo
 
     render() {
         return !SelectionManager.Views().length ? null : (
-            <div className="preroptiesDocBacklinksSelector">
+            <div className="propertiesDocBacklinksSelector">
                 {this.props.hideTitle ? null : <p key="contexts">Contexts:</p>}
                 <LinkMenu docView={SelectionManager.Views().lastElement()} clearLinkEditor={undefined} itemHandler={this.getOnClick} style={{ left: 0, top: 0 }} />
             </div>
diff --git a/src/client/views/PropertiesDocContextSelector.tsx b/src/client/views/PropertiesDocContextSelector.tsx
index e1279c9a7..6cac7b0fe 100644
--- a/src/client/views/PropertiesDocContextSelector.tsx
+++ b/src/client/views/PropertiesDocContextSelector.tsx
@@ -53,6 +53,7 @@ export class PropertiesDocContextSelector extends React.Component<PropertiesDocC
     };
 
     render() {
+        if (this._docs.length < 1) return undefined
         return (
             <div>
                 {this.props.hideTitle ? null : <p key="contexts">Contexts:</p>}
diff --git a/src/client/views/PropertiesSection.scss b/src/client/views/PropertiesSection.scss
new file mode 100644
index 000000000..79479a4ce
--- /dev/null
+++ b/src/client/views/PropertiesSection.scss
@@ -0,0 +1,24 @@
+@import './global/globalCssVariables.scss';
+
+.propertiesView-section {
+    
+    .propertiesView-content {
+        padding: 10px;
+    }
+    
+    .propertiesView-sectionTitle {
+        text-align: center;
+        display: flex;
+        padding: 10px;
+        font-size: 14px;
+        font-weight: bold;
+        justify-content: space-between;
+        align-items: center;
+    
+        .propertiesView-sectionTitle-icon {
+            width: 20px;
+            height: 20px;
+            align-items: flex-end;
+        }
+    }
+}
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx
new file mode 100644
index 000000000..b900d17ca
--- /dev/null
+++ b/src/client/views/PropertiesSection.tsx
@@ -0,0 +1,51 @@
+import React = require('react');
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
+import { action, computed } from "mobx"
+import { observer } from "mobx-react"
+import './PropertiesSection.scss'
+import { Doc } from '../../fields/Doc';
+import { StrCast } from '../../fields/Types';
+
+export interface PropertiesSectionProps {
+    title: string, 
+    content?: JSX.Element | string | null, 
+    isOpen: boolean,
+    setIsOpen: (bool: boolean) => any 
+    inSection?: boolean,
+    setInSection?: (bool: boolean) => any 
+}
+
+@observer
+export class PropertiesSection extends React.Component<PropertiesSectionProps> {
+    @computed get color() {
+        return StrCast(Doc.UserDoc().userColor);
+    }
+
+    @computed get backgroundColor() {
+        return StrCast(Doc.UserDoc().userBackgroundColor);
+    }
+
+    @computed get variantColor() {
+        return StrCast(Doc.UserDoc().userVariantColor);
+    }
+    render() {
+        console.log(this.props.title, this.props.content)
+        if (this.props.content === undefined || this.props.content === null) return null
+        else return <div className="propertiesView-section" onPointerEnter={action(() => (this.props.setInSection && this.props.setInSection(true)))} onPointerLeave={action(() => (this.props.setInSection && this.props.setInSection(false)))}>
+        <div className="propertiesView-sectionTitle" onPointerDown={action(() => (this.props.setIsOpen(!this.props.isOpen)))} style={{ 
+            background: this.props.isOpen ?  this.variantColor : this.backgroundColor,
+            color: this.color
+        }}>
+            {this.props.title}
+            <div className="propertiesView-sectionTitle-icon">
+                <FontAwesomeIcon icon={this.props.isOpen ? 'caret-down' : 'caret-right'} size="lg"  />
+            </div>
+        </div>
+        {!this.props.isOpen ? null :
+            <div className="propertiesView-content">
+                {this.props.content}
+            </div>
+        }
+    </div>
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index 897be9a32..889f5d5cf 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -6,122 +6,31 @@
     font-family: 'Roboto';
     font-size: 12px;
     cursor: auto;
+    border-left: $standard-border;
 
     .slider-text {
         font-size: 8px;
     }
 
-    overflow-x: hidden;
-    overflow-y: auto;
-
     .propertiesView-title {
-        text-align: center;
-        padding-top: 12px;
-        padding-bottom: 12px;
-        display: flex;
-        font-size: 18px;
+        padding: 10px;
+        font-size: 24px;
         font-weight: bold;
-        justify-content: center;
-
-        .propertiesView-title-icon {
-            width: 20px;
-            height: 20px;
-            padding-left: 38px;
-            margin-top: -5px;
-            align-items: flex-end;
-            margin-left: auto;
-            margin-right: 10px;
-
-            &:hover {
-                color: grey;
-                cursor: pointer;
-            }
-        }
     }
 
-    .propertiesView-name {
-        border-bottom: 1px solid black;
-        padding: 8.5px;
-        font-size: 12.5px;
+    overflow-x: hidden;
+    overflow-y: auto;
 
-        &:hover {
-            cursor: text;
-        }
+    .propertiesView-name,
+    .propertiesView-type {
+        padding: 0px 10px;
     }
 
-    .propertiesView-settings {
-        //border-bottom: 1px solid black;
-        //padding: 8.5px;
-        font-size: 12.5px;
-        font-weight: bold;
-
-        .propertiesView-settings-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-settings-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-settings-content {
-            margin-left: 12px;
-            padding-bottom: 10px;
-            padding-top: 8px;
-        }
-    }
 
     .propertiesView-sharing {
         //border-bottom: 1px solid black;
         //padding: 8.5px;
 
-        .propertiesView-sharing-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-sharing-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-sharing-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
 
             .propertiesView-buttonContainer {
                 float: right;
@@ -157,40 +66,13 @@
                     width: 100%;
                 }
             }
-        }
     }
 
     .propertiesView-filters {
         //border-bottom: 1px solid black;
         //padding: 8.5px;
 
-        .propertiesView-filters-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-filters-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-filters-content {
+        .propertiesView-content {
             font-size: 10px;
             padding: 10px;
             margin-left: 5px;
@@ -219,85 +101,10 @@
         }
     }
 
-    .propertiesView-appearance {
-        //border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-appearance-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-appearance-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-appearance-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
-    }
-
-    .propertiesView-transform {
-        //border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-transform-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-transform-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-transform-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
-    }
-
     .notify-button {
         padding: 2px;
         width: 12px;
         height: 12px;
-        background-color: black;
         border-radius: 10px;
         padding-left: 2px;
         padding-right: 2px;
@@ -393,58 +200,6 @@
         }
     }
 
-    .propertiesView-fields {
-        //border-bottom: 1px solid black;
-        //padding: 8.5px;
-
-        .propertiesView-fields-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-fields-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-fields-checkbox {
-            float: right;
-            height: 20px;
-            margin-top: -9px;
-
-            .propertiesView-fields-checkbox-text {
-                font-size: 7px;
-                margin-top: -10px;
-                margin-left: 6px;
-            }
-        }
-
-        .propertiesView-fields-content {
-            font-size: 10px;
-            margin-left: 2px;
-            padding: 10px;
-
-            &:hover {
-                cursor: pointer;
-            }
-        }
-    }
 
     .propertiesView-field {
         display: flex;
@@ -466,109 +221,14 @@
         }
     }
 
-    .propertiesView-contexts {
-        .propertiesView-contexts-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-contexts-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-contexts-content {
-            overflow: hidden;
-            padding: 10px;
-        }
-    }
-
-    .propertiesView-layout {
-        .propertiesView-layout-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-layout-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-layout-content {
-            overflow: hidden;
-            padding: 10px;
-        }
     }
 
     .propertiesView-presTrails {
         //border-bottom: 1px solid black;
         //padding: 8.5px;
 
-        .propertiesView-presTrails-title {
-            font-weight: bold;
-            font-size: 12.5px;
-            padding: 4px;
-            display: flex;
-            color: white;
-            padding-left: 8px;
-            background-color: rgb(51, 51, 51);
-
-            &:hover {
-                cursor: pointer;
-            }
-
-            .propertiesView-presTrails-title-icon {
-                float: right;
-                justify-items: right;
-                align-items: flex-end;
-                margin-left: auto;
-                margin-right: 9px;
-
-                &:hover {
-                    cursor: pointer;
-                }
-            }
-        }
-
-        .propertiesView-presTrails-content {
-            font-size: 10px;
-            padding: 10px;
-            margin-left: 5px;
-        }
+      
     }
-}
 
 .inking-button {
     display: flex;
@@ -847,10 +507,6 @@
     padding: 5%;
 }
 
-.propertiesView-section {
-    padding-left: 20px;
-}
-
 .propertiesView-input {
     padding: 4px 8px;
 
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 09aac053a..e86506f92 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -35,6 +35,8 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector
 import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
 import './PropertiesView.scss';
 import { DefaultStyleProvider } from './StyleProvider';
+import { Button, EditableText, NumberDropdown, Size, Slider, Type } from 'browndash-components';
+import { PropertiesSection } from './PropertiesSection';
 const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -332,7 +334,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         return (
             <Tooltip title={<div className="dash-tooltip">Notify with message</div>}>
                 <div className="notify-button">
-                    <FontAwesomeIcon className="notify-button-icon" icon="bell" color="white" size="sm" />
+                    <FontAwesomeIcon className="notify-button-icon" icon="bell"  size="sm" />
                 </div>
             </Tooltip>
         );
@@ -435,29 +437,57 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @action
     toggleCheckbox = () => (this.layoutFields = !this.layoutFields);
 
+    @computed get color() {
+        return StrCast(Doc.UserDoc().userColor);
+    }
+
+    @computed get backgroundColor() {
+        return StrCast(Doc.UserDoc().userBackgroundColor);
+    }
+
+    @computed get variantColor() {
+        return StrCast(Doc.UserDoc().userVariantColor);
+    }
+
     @computed get editableTitle() {
         const titles = new Set<string>();
-        SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
         const title = Array.from(titles.keys()).length > 1 ? '--multiple selected--' : StrCast(this.selectedDoc?.title);
+        SelectionManager.Views().forEach(dv => titles.add(StrCast(dv.rootDoc.title)));
         return (
-            <div className="editable-title">
-                <EditableView key="editableView" contents={title} height={25} fontSize={14} GetValue={() => title} SetValue={this.setTitle} />
-            </div>
+            <EditableText
+                val={title}
+                setVal={this.setTitle}
+                color={this.color}
+                type={Type.SEC}
+                formLabel={"Title"}
+                fillWidth
+            />
+        );
+    }
+
+    @computed get type() {
+        const type = StrCast(this.selectedDoc?.type);
+        return (
+            <Button
+                formLabel={"Type"}
+                text={type}
+                color={this.color}
+                align='flex-start'
+                fillWidth
+            />
         );
     }
 
     @undoBatch
     @action
-    setTitle = (value: string) => {
+    setTitle = (value: string | number) => {
+        console.log(value)
         if (SelectionManager.Views().length > 1) {
             SelectionManager.Views().map(dv => Doc.SetInPlace(dv.rootDoc, 'title', value, true));
-            return true;
         } else if (this.dataDoc) {
             if (this.selectedDoc) Doc.SetInPlace(this.selectedDoc, 'title', value, true);
-            else KeyValueBox.SetField(this.dataDoc, 'title', value, true);
-            return true;
+            else KeyValueBox.SetField(this.dataDoc, 'title', value as string, true);
         }
-        return false;
     };
 
     @undoBatch
@@ -515,7 +545,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                         className="inking-button-points"
                         style={{ backgroundColor: InkStrokeProperties.Instance._controlButton ? 'black' : '' }}
                         onPointerDown={action(() => (InkStrokeProperties.Instance._controlButton = !InkStrokeProperties.Instance._controlButton))}>
-                        <FontAwesomeIcon icon="bezier-curve" color="white" size="lg" />
+                        <FontAwesomeIcon icon="bezier-curve"  size="lg" />
                     </div>
                 </Tooltip>
             </div>
@@ -534,10 +564,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} onKeyPress={e => e.stopPropagation()} />
                 <div className="inputBox-button">
                     <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
-                        <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                        <FontAwesomeIcon icon="caret-up"  size="sm" />
                     </div>
                     <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
-                        <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                        <FontAwesomeIcon icon="caret-down"  size="sm" />
                     </div>
                 </div>
             </div>
@@ -791,10 +821,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <input className="inputBox-input" type="text" value={value} onChange={e => setter(e.target.value)} />
                 <div className="inputBox-button">
                     <div className="inputBox-button-up" key="up2" onPointerDown={undoBatch(action(() => this.upDownButtons('up', key)))}>
-                        <FontAwesomeIcon icon="caret-up" color="white" size="sm" />
+                        <FontAwesomeIcon icon="caret-up"  size="sm" />
                     </div>
                     <div className="inputbox-Button-down" key="down2" onPointerDown={undoBatch(action(() => this.upDownButtons('down', key)))}>
-                        <FontAwesomeIcon icon="caret-down" color="white" size="sm" />
+                        <FontAwesomeIcon icon="caret-down"  size="sm" />
                     </div>
                 </div>
             </div>
@@ -884,6 +914,29 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         return (
             <div className="transform-editor">
                 {this.isInk ? this.controlPointsButton : null}
+                <Slider 
+                    formLabel={'Height'} 
+                    multithumb={false}
+                    color={this.color}
+                    size={Size.XSMALL} 
+                    min={0} 
+                    max={1000} 
+                    number={Number(this.shapeHgt)}
+                    setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height')}
+                    fillWidth
+                />
+                <Slider 
+                    formLabel={'Width'} 
+                    multithumb={false}
+                    color={this.color}
+                    size={Size.XSMALL} 
+                    min={0} 
+                    max={1000} 
+                    number={Number(this.shapeWid)}
+                    setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width')}
+                    fillWidth
+                />
+
                 {this.hgtInput}
                 {this.XpsInput}
             </div>
@@ -891,52 +944,38 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     }
 
     @computed get optionsSubMenu() {
-        return (
-            <div className="propertiesView-settings" onPointerEnter={action(() => (this.inOptions = true))} onPointerLeave={action(() => (this.inOptions = false))}>
-                <div className="propertiesView-settings-title" onPointerDown={action(() => (this.openOptions = !this.openOptions))} style={{ backgroundColor: this.openOptions ? 'black' : '' }}>
-                    Options
-                    <div className="propertiesView-settings-title-icon">
-                        <FontAwesomeIcon icon={this.openOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {!this.openOptions ? null : (
-                    <div className="propertiesView-settings-content">
-                        <PropertiesButtons />
-                    </div>
-                )}
-            </div>
-        );
+        return <PropertiesSection
+            title="Options"
+            content={<PropertiesButtons />}
+            inSection={this.inOptions}
+            isOpen={this.openOptions}
+            setInSection={(bool) => this.inOptions = bool}
+            setIsOpen={(bool) => this.openOptions = bool}
+        />
     }
 
     @computed get sharingSubMenu() {
-        return (
-            <div className="propertiesView-sharing">
-                <div className="propertiesView-sharing-title" onPointerDown={action(() => (this.openSharing = !this.openSharing))} style={{ backgroundColor: this.openSharing ? 'black' : '' }}>
-                    Sharing {'&'} Permissions
-                    <div className="propertiesView-sharing-title-icon">
-                        <FontAwesomeIcon icon={this.openSharing ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {!this.openSharing ? null : (
-                    <div className="propertiesView-sharing-content">
-                        <div className="propertiesView-buttonContainer">
-                            {!Doc.noviceMode ? (
-                                <div className="propertiesView-acls-checkbox">
-                                    <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} />
-                                    <div className="propertiesView-acls-checkbox-text">Layout</div>
-                                </div>
-                            ) : null}
-                            {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}>
-                                        <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
-                                            <FontAwesomeIcon icon="redo-alt" color="white" size="1x" />
-                                        </button>
-                                    </Tooltip> */}
+        return <PropertiesSection
+            title="Sharing & Permissions"
+            content={<>
+            <div className="propertiesView-buttonContainer">
+                {!Doc.noviceMode ? (
+                        <div className="propertiesView-acls-checkbox">
+                            <Checkbox color="primary" onChange={action(() => (this.layoutDocAcls = !this.layoutDocAcls))} checked={this.layoutDocAcls} />
+                            <div className="propertiesView-acls-checkbox-text">Layout</div>
                         </div>
-                        {this.sharingTable}
-                    </div>
-                )}
-            </div>
-        );
+                    ) : null}
+                    {/* <Tooltip title={<><div className="dash-tooltip">{"Re-distribute sharing settings"}</div></>}>
+                        <button onPointerDown={() => SharingManager.Instance.distributeOverCollection(this.selectedDoc!)}>
+                            <FontAwesomeIcon icon="redo-alt"  size="1x" />
+                        </button>
+                    </Tooltip> */}
+                </div>
+                {this.sharingTable}
+            </>}
+            isOpen={this.openSharing}
+            setIsOpen={(bool) => this.openSharing = bool}
+        />
     }
 
     /**
@@ -964,111 +1003,71 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     };
 
     @computed get filtersSubMenu() {
-        return (
-            <div className="propertiesView-filters">
-                <div className="propertiesView-filters-title" onPointerDown={action(() => (this.openFilters = !this.openFilters))} style={{ backgroundColor: this.openFilters ? 'black' : '' }}>
-                    Filters
-                    <div className="propertiesView-filters-title-icon">
-                        <FontAwesomeIcon icon={this.openFilters ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {!this.openFilters ? null : (
-                    <div className="propertiesView-filters-content" style={{ position: 'relative', height: 'auto' }}>
-                        <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
-                    </div>
-                )}
-            </div>
-        );
+        return <PropertiesSection 
+            title="Filters"
+            content={<div className="propertiesView-content filters" style={{ position: 'relative', height: 'auto' }}>
+                <FilterPanel rootDoc={this.selectedDoc ?? Doc.ActiveDashboard!} />
+            </div>}
+            isOpen={this.openFilters}
+            setIsOpen={(bool) => this.openFilters = bool}
+        />
     }
 
     @computed get inkSubMenu() {
         return (
             <>
-                {!this.isInk ? null : (
-                    <div className="propertiesView-appearance">
-                        <div className="propertiesView-appearance-title" onPointerDown={action(() => (this.openAppearance = !this.openAppearance))} style={{ backgroundColor: this.openAppearance ? 'black' : '' }}>
-                            Appearance
-                            <div className="propertiesView-appearance-title-icon">
-                                <FontAwesomeIcon icon={this.openAppearance ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                            </div>
-                        </div>
-                        {!this.openAppearance ? null : <div className="propertiesView-appearance-content">{this.appearanceEditor}</div>}
-                    </div>
-                )}
-
-                <div className="propertiesView-transform">
-                    <div className="propertiesView-transform-title" onPointerDown={action(() => (this.openTransform = !this.openTransform))} style={{ backgroundColor: this.openTransform ? 'black' : '' }}>
-                        Transform
-                        <div className="propertiesView-transform-title-icon">
-                            <FontAwesomeIcon icon={this.openTransform ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                        </div>
-                    </div>
-                    {this.openTransform ? <div className="propertiesView-transform-content">{this.transformEditor}</div> : null}
-                </div>
+                <PropertiesSection
+                    title="Appearance"
+                    content={this.isInk ? this.appearanceEditor : null}
+                    isOpen={this.openAppearance}
+                    setIsOpen={(bool) => this.openAppearance = bool}
+                />
+                <PropertiesSection
+                    title="Transform"
+                    content={this.transformEditor}
+                    isOpen={this.openTransform}
+                    setIsOpen={(bool) => this.openTransform = bool}
+                />
             </>
         );
     }
 
     @computed get fieldsSubMenu() {
-        return (
-            <div className="propertiesView-fields">
-                <div className="propertiesView-fields-title" onPointerDown={action(() => (this.openFields = !this.openFields))} style={{ backgroundColor: this.openFields ? 'black' : '' }}>
-                    Fields {'&'} Tags
-                    <div className="propertiesView-fields-title-icon">
-                        <FontAwesomeIcon icon={this.openFields ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {!Doc.noviceMode && this.openFields ? (
-                    <div className="propertiesView-fields-checkbox">
-                        {this.fieldsCheckbox}
-                        <div className="propertiesView-fields-checkbox-text">Layout</div>
-                    </div>
-                ) : null}
-                {!this.openFields ? null : <div className="propertiesView-fields-content">{Doc.noviceMode ? this.noviceFields : this.expandedField}</div>}
-            </div>
-        );
+        return <PropertiesSection
+            title="Fields & Tags"
+            content={<div className="propertiesView-content fields">{
+                Doc.noviceMode ? this.noviceFields : this.expandedField}
+            </div>}
+            isOpen={this.openFields}
+            setIsOpen={(bool) => this.openFields = bool}
+        />
     }
 
     @computed get contextsSubMenu() {
-        return (
-            <div className="propertiesView-contexts">
-                <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openContexts = !this.openContexts))} style={{ backgroundColor: this.openContexts ? 'black' : '' }}>
-                    Other Contexts
-                    <div className="propertiesView-contexts-title-icon">
-                        <FontAwesomeIcon icon={this.openContexts ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {this.openContexts ? <div className="propertiesView-contexts-content">{this.contexts}</div> : null}
-            </div>
-        );
+        return <PropertiesSection
+            title="Other Contexts"
+            content={this.contexts}
+            isOpen={this.openContexts}
+            setIsOpen={(bool) => this.openContexts = bool}
+        />
     }
 
     @computed get linksSubMenu() {
-        return (
-            <div className="propertiesView-contexts">
-                <div className="propertiesView-contexts-title" onPointerDown={action(() => (this.openLinks = !this.openLinks))} style={{ backgroundColor: this.openLinks ? 'black' : '' }}>
-                    Linked To
-                    <div className="propertiesView-contexts-title-icon">
-                        <FontAwesomeIcon icon={this.openLinks ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {this.openLinks ? <div className="propertiesView-contexts-content">{this.links}</div> : null}
-            </div>
-        );
+        return <PropertiesSection
+            title="Linked To"
+            content={this.links}
+            isOpen={this.openLinks}
+            setIsOpen={(bool) => this.openLinks = bool}
+        />
     }
 
     @computed get layoutSubMenu() {
-        return (
-            <div className="propertiesView-layout">
-                <div className="propertiesView-layout-title" onPointerDown={action(() => (this.openLayout = !this.openLayout))} style={{ backgroundColor: this.openLayout ? 'black' : '' }}>
-                    Layout
-                    <div className="propertiesView-layout-title-icon">
-                        <FontAwesomeIcon icon={this.openLayout ? 'caret-down' : 'caret-right'} size="lg" color="white" />
-                    </div>
-                </div>
-                {this.openLayout ? <div className="propertiesView-layout-content">{this.layoutPreview}</div> : null}
-            </div>
-        );
+        return <PropertiesSection
+            title="Layout"
+            content={this.layoutPreview}
+            isOpen={this.openLayout}
+            setIsOpen={(bool) => this.openLayout = bool}
+        />
     }
 
     @computed get description() {
@@ -1269,6 +1268,226 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         if (scale > 1) scale = 1;
         this.sourceAnchor && (this.sourceAnchor.followLinkZoomScale = scale);
     };
+    
+    @computed get linkProperties() {
+        const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
+        const targZoom = this.sourceAnchor?.followLinkZoom;
+        const indent = 30;
+        const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
+
+        return <>
+        <div className="propertiesView-section" style={{ background: 'darkgray' }}>
+            <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+                <p>Relationship</p>
+                {this.editRelationship}
+            </div>
+            <div className="propertiesView-input" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
+                <p>Description</p>
+                {this.editDescription}
+            </div>
+            <div className="propertiesView-input inline">
+                <p>Show link</p>
+                <button
+                    style={{ background: !LinkManager.currentLink?.link_displayLine ? '' : '#4476f7', borderRadius: 3 }}
+                    onPointerDown={e => this.toggleLinkProp(e, 'link_displayLine')}
+                    onClick={e => e.stopPropagation()}
+                    className="propertiesButton">
+                    <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+                </button>
+            </div>
+            <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+                <p>Auto-move anchors</p>
+                <button
+                    style={{ background: !LinkManager.currentLink?.link_autoMoveAnchors ? '' : '#4476f7', borderRadius: 3 }}
+                    onPointerDown={e => this.toggleLinkProp(e, 'link_autoMoveAnchors')}
+                    onClick={e => e.stopPropagation()}
+                    className="propertiesButton">
+                    <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                </button>
+            </div>
+            <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
+                <p>Display arrow</p>
+                <button
+                    style={{ background: !LinkManager.currentLink?.link_displayArrow ? '' : '#4476f7', borderRadius: 3 }}
+                    onPointerDown={e => this.toggleLinkProp(e, 'link_displayArrow')}
+                    onClick={e => e.stopPropagation()}
+                    className="propertiesButton">
+                    <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+                </button>
+            </div>
+        </div>
+        {!hasSelectedAnchor ? null : (
+            <div className="propertiesView-section">
+                <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
+                    <p>Follow by</p>
+                    <select onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)} value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
+                        <option value={undefined}>Default</option>
+                        <option value={OpenWhere.addLeft}>Opening in new left pane</option>
+                        <option value={OpenWhere.addRight}>Opening in new right pane</option>
+                        <option value={OpenWhere.replaceLeft}>Replacing left tab</option>
+                        <option value={OpenWhere.replaceRight}>Replacing right tab</option>
+                        <option value={OpenWhere.fullScreen}>Overlaying current tab</option>
+                        <option value={OpenWhere.lightbox}>Opening in lightbox</option>
+                        <option value={OpenWhere.add}>Opening in new tab</option>
+                        <option value={OpenWhere.replace}>Replacing current tab</option>
+                        <option value={OpenWhere.inParent}>Opening in same collection</option>
+                        {LinkManager.currentLink?.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
+                    </select>
+                </div>
+                <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
+                    <p>Animation</p>
+                    <select style={{ width: '100%', gridColumn: 2 }} onChange={e => this.changeAnimationBehavior(e.currentTarget.value)} value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
+                        <option value="default">Default</option>
+                        {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
+                            <option key={effect.toString()} value={effect.toString()}>
+                                {effect.toString()}
+                            </option>
+                        ))}
+                    </select>
+                    <div className="effectDirection" style={{ marginLeft: '10px', display: 'grid', width: 40, height: 36, gridColumn: 3, gridTemplateRows: '12px 12px 12px' }}>
+                        {this.animationDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
+                        {this.animationDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
+                        {this.animationDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
+                        {this.animationDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
+                        {this.animationDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
+                    </div>
+                </div>
+                {PresBox.inputter(
+                    '0.1',
+                    '0.1',
+                    '10',
+                    NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
+                    true,
+                    (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
+                    indent
+                )}{' '}
+                <div
+                    className={'slider-headers'}
+                    style={{
+                        display: 'grid',
+                        justifyContent: 'space-between',
+                        width: `calc(100% - ${indent * 2}px)`,
+                        marginLeft: indent,
+                        marginRight: indent,
+                        gridTemplateColumns: 'auto auto',
+                        borderTop: 'solid',
+                    }}>
+                    <div className="slider-text">Fast</div>
+                    <div className="slider-text">Slow</div>
+                </div>{' '}
+                <div className="propertiesView-input inline">
+                    <p>Play Target Audio</p>
+                    <button
+                        style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Zoom Text Selections</p>
+                    <button
+                        style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Toggle Follow to Outer Context</p>
+                    <button
+                        style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Toggle Target (Show/Hide)</p>
+                    <button
+                        style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Ease Transitions</p>
+                    <button
+                        style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Capture Offset to Target</p>
+                    <button
+                        style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => {
+                            this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
+                            this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
+                        }}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline">
+                    <p>Center Target (no zoom)</p>
+                    <button
+                        style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
+                    </button>
+                </div>
+                <div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
+                    <p>Zoom %</p>
+                    <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
+                        <input className="presBox-input" style={{ width: '100%' }} readOnly={true} type="number" value={zoom} />
+                        <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
+                            <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
+                                <FontAwesomeIcon icon={'caret-up'} />
+                            </div>
+                            <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
+                                <FontAwesomeIcon icon={'caret-down'} />
+                            </div>
+                        </div>
+                    </div>
+                    <button
+                        style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
+                        onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
+                        onClick={e => e.stopPropagation()}
+                        className="propertiesButton">
+                        <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
+                    </button>
+                </div>
+                {!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
+                <div
+                    className={'slider-headers'}
+                    style={{
+                        display: !targZoom ? 'none' : 'grid',
+                        justifyContent: 'space-between',
+                        width: `calc(100% - ${indent * 2}px)`,
+                        marginLeft: indent,
+                        marginRight: indent,
+                        gridTemplateColumns: 'auto auto',
+                        borderTop: 'solid',
+                    }}>
+                    <div className="slider-text">0%</div>
+                    <div className="slider-text">100%</div>
+                </div>{' '}
+            </div>
+        )}
+    </>
+    }
 
     /**
      * Handles adding and removing members from the sharing panel
@@ -1283,9 +1502,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     render() {
         const isNovice = Doc.noviceMode;
-        const zoom = Number((NumCast(this.sourceAnchor?.followLinkZoomScale, 1) * 100).toPrecision(3));
-        const targZoom = this.sourceAnchor?.followLinkZoom;
-        const indent = 30;
         const hasSelectedAnchor = LinkManager.Links(this.sourceAnchor).includes(LinkManager.currentLink!);
         if (!this.selectedDoc && !this.isPres) {
             return (
@@ -1301,243 +1517,26 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                     <div
                         className="propertiesView"
                         style={{
+                            background: StrCast(Doc.UserDoc().userBackgroundColor),
+                            color: StrCast(Doc.UserDoc().userColor),
                             width: this.props.width,
                             minWidth: this.props.width,
-                            //overflowY: this.scrolling ? "scroll" : "visible"
                         }}>
                         <div className="propertiesView-title" style={{ width: this.props.width }}>
                             Properties
                         </div>
                         <div className="propertiesView-name">{this.editableTitle}</div>
-
+                        <div className="propertiesView-type">{this.type}</div>
                         {this.contextsSubMenu}
-
                         {this.linksSubMenu}
                         {!this.selectedDoc || !LinkManager.currentLink || (!hasSelectedAnchor && this.selectedDoc !== LinkManager.currentLink) ? null : (
-                            <>
-                                <div className="propertiesView-section" style={{ background: 'darkgray' }}>
-                                    <div className="propertiesView-input first" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
-                                        <p>Relationship</p>
-                                        {this.editRelationship}
-                                    </div>
-                                    <div className="propertiesView-input" style={{ display: 'grid', gridTemplateColumns: '84px auto' }}>
-                                        <p>Description</p>
-                                        {this.editDescription}
-                                    </div>
-                                    <div className="propertiesView-input inline">
-                                        <p>Show link</p>
-                                        <button
-                                            style={{ background: !LinkManager.currentLink?.link_displayLine ? '' : '#4476f7', borderRadius: 3 }}
-                                            onPointerDown={e => this.toggleLinkProp(e, 'link_displayLine')}
-                                            onClick={e => e.stopPropagation()}
-                                            className="propertiesButton">
-                                            <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
-                                        </button>
-                                    </div>
-                                    <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
-                                        <p>Auto-move anchors</p>
-                                        <button
-                                            style={{ background: !LinkManager.currentLink?.link_autoMoveAnchors ? '' : '#4476f7', borderRadius: 3 }}
-                                            onPointerDown={e => this.toggleLinkProp(e, 'link_autoMoveAnchors')}
-                                            onClick={e => e.stopPropagation()}
-                                            className="propertiesButton">
-                                            <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                        </button>
-                                    </div>
-                                    <div className="propertiesView-input inline" style={{ marginLeft: 10 }}>
-                                        <p>Display arrow</p>
-                                        <button
-                                            style={{ background: !LinkManager.currentLink?.link_displayArrow ? '' : '#4476f7', borderRadius: 3 }}
-                                            onPointerDown={e => this.toggleLinkProp(e, 'link_displayArrow')}
-                                            onClick={e => e.stopPropagation()}
-                                            className="propertiesButton">
-                                            <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
-                                        </button>
-                                    </div>
-                                </div>
-                                {!hasSelectedAnchor ? null : (
-                                    <div className="propertiesView-section">
-                                        <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 84px)' }}>
-                                            <p>Follow by</p>
-                                            <select onChange={e => this.changeFollowBehavior(e.currentTarget.value === 'Default' ? undefined : e.currentTarget.value)} value={Cast(this.sourceAnchor?.followLinkLocation, 'string', null)}>
-                                                <option value={undefined}>Default</option>
-                                                <option value={OpenWhere.addLeft}>Opening in new left pane</option>
-                                                <option value={OpenWhere.addRight}>Opening in new right pane</option>
-                                                <option value={OpenWhere.replaceLeft}>Replacing left tab</option>
-                                                <option value={OpenWhere.replaceRight}>Replacing right tab</option>
-                                                <option value={OpenWhere.fullScreen}>Overlaying current tab</option>
-                                                <option value={OpenWhere.lightbox}>Opening in lightbox</option>
-                                                <option value={OpenWhere.add}>Opening in new tab</option>
-                                                <option value={OpenWhere.replace}>Replacing current tab</option>
-                                                <option value={OpenWhere.inParent}>Opening in same collection</option>
-                                                {LinkManager.currentLink?.linksToAnnotation ? <option value="openExternal">Open in external page</option> : null}
-                                            </select>
-                                        </div>
-                                        <div className="propertiesView-input inline first" style={{ display: 'grid', gridTemplateColumns: '84px calc(100% - 134px) 50px' }}>
-                                            <p>Animation</p>
-                                            <select style={{ width: '100%', gridColumn: 2 }} onChange={e => this.changeAnimationBehavior(e.currentTarget.value)} value={StrCast(this.sourceAnchor?.followLinkAnimEffect, 'default')}>
-                                                <option value="default">Default</option>
-                                                {[PresEffect.None, PresEffect.Zoom, PresEffect.Lightspeed, PresEffect.Fade, PresEffect.Flip, PresEffect.Rotate, PresEffect.Bounce, PresEffect.Roll].map(effect => (
-                                                    <option key={effect.toString()} value={effect.toString()}>
-                                                        {effect.toString()}
-                                                    </option>
-                                                ))}
-                                            </select>
-                                            <div className="effectDirection" style={{ marginLeft: '10px', display: 'grid', width: 40, height: 36, gridColumn: 3, gridTemplateRows: '12px 12px 12px' }}>
-                                                {this.animationDirection(PresEffectDirection.Left, 'angle-right', 1, 2, {})}
-                                                {this.animationDirection(PresEffectDirection.Right, 'angle-left', 3, 2, {})}
-                                                {this.animationDirection(PresEffectDirection.Top, 'angle-down', 2, 1, {})}
-                                                {this.animationDirection(PresEffectDirection.Bottom, 'angle-up', 2, 3, {})}
-                                                {this.animationDirection(PresEffectDirection.Center, '', 2, 2, { width: 10, height: 10, alignSelf: 'center' })}
-                                            </div>
-                                        </div>
-                                        {PresBox.inputter(
-                                            '0.1',
-                                            '0.1',
-                                            '10',
-                                            NumCast(this.sourceAnchor?.followLinkTransitionTime) / 1000,
-                                            true,
-                                            (val: string) => PresBox.SetTransitionTime(val, (timeInMS: number) => this.sourceAnchor && (this.sourceAnchor.followLinkTransitionTime = timeInMS)),
-                                            indent
-                                        )}{' '}
-                                        <div
-                                            className={'slider-headers'}
-                                            style={{
-                                                display: 'grid',
-                                                justifyContent: 'space-between',
-                                                width: `calc(100% - ${indent * 2}px)`,
-                                                marginLeft: indent,
-                                                marginRight: indent,
-                                                gridTemplateColumns: 'auto auto',
-                                                borderTop: 'solid',
-                                            }}>
-                                            <div className="slider-text">Fast</div>
-                                            <div className="slider-text">Slow</div>
-                                        </div>{' '}
-                                        <div className="propertiesView-input inline">
-                                            <p>Play Target Audio</p>
-                                            <button
-                                                style={{ background: !this.sourceAnchor?.followLinkAudio ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkAudio', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Zoom Text Selections</p>
-                                            <button
-                                                style={{ background: !this.sourceAnchor?.followLinkZoomText ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoomText', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Toggle Follow to Outer Context</p>
-                                            <button
-                                                style={{ background: !this.sourceAnchor?.followLinkToOuterContext ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToOuterContext', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faWindowMaximize as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Toggle Target (Show/Hide)</p>
-                                            <button
-                                                style={{ background: !this.sourceAnchor?.followLinkToggle ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkToggle', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Ease Transitions</p>
-                                            <button
-                                                style={{ background: this.sourceAnchor?.followLinkEase === 'linear' ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkEase', this.sourceAnchor, 'ease', 'linear')}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Capture Offset to Target</p>
-                                            <button
-                                                style={{ background: this.sourceAnchor?.followLinkXoffset === undefined ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => {
-                                                    this.toggleAnchorProp(e, 'followLinkXoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.x) - NumCast(this.sourceAnchor?.x), undefined);
-                                                    this.toggleAnchorProp(e, 'followLinkYoffset', this.sourceAnchor, NumCast(this.destinationAnchor?.y) - NumCast(this.sourceAnchor?.y), undefined);
-                                                }}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline">
-                                            <p>Center Target (no zoom)</p>
-                                            <button
-                                                style={{ background: this.sourceAnchor?.followLinkZoom ? '' : '#4476f7', borderRadius: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faAnchor as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        <div className="propertiesView-input inline" style={{ display: 'grid', gridTemplateColumns: '78px calc(100% - 108px) 50px' }}>
-                                            <p>Zoom %</p>
-                                            <div className="ribbon-property" style={{ display: !targZoom ? 'none' : 'inline-flex' }}>
-                                                <input className="presBox-input" style={{ width: '100%' }} readOnly={true} type="number" value={zoom} />
-                                                <div className="ribbon-propertyUpDown" style={{ display: 'flex', flexDirection: 'column' }}>
-                                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), 0.1))}>
-                                                        <FontAwesomeIcon icon={'caret-up'} />
-                                                    </div>
-                                                    <div className="ribbon-propertyUpDownItem" onClick={undoBatch(() => this.setZoom(String(zoom), -0.1))}>
-                                                        <FontAwesomeIcon icon={'caret-down'} />
-                                                    </div>
-                                                </div>
-                                            </div>
-                                            <button
-                                                style={{ background: !targZoom || this.sourceAnchor?.followLinkZoomScale === 0 ? '' : '#4476f7', borderRadius: 3, gridColumn: 3 }}
-                                                onPointerDown={e => this.toggleAnchorProp(e, 'followLinkZoom', this.sourceAnchor)}
-                                                onClick={e => e.stopPropagation()}
-                                                className="propertiesButton">
-                                                <FontAwesomeIcon className="fa-icon" icon={faArrowRight as IconLookup} size="lg" />
-                                            </button>
-                                        </div>
-                                        {!targZoom ? null : PresBox.inputter('0', '1', '100', zoom, true, this.setZoom, 30)}
-                                        <div
-                                            className={'slider-headers'}
-                                            style={{
-                                                display: !targZoom ? 'none' : 'grid',
-                                                justifyContent: 'space-between',
-                                                width: `calc(100% - ${indent * 2}px)`,
-                                                marginLeft: indent,
-                                                marginRight: indent,
-                                                gridTemplateColumns: 'auto auto',
-                                                borderTop: 'solid',
-                                            }}>
-                                            <div className="slider-text">0%</div>
-                                            <div className="slider-text">100%</div>
-                                        </div>{' '}
-                                    </div>
-                                )}
-                            </>
+                            this.linkProperties
                         )}
-
                         {this.inkSubMenu}
-
                         {this.optionsSubMenu}
-
                         {this.fieldsSubMenu}
-
                         {isNovice ? null : this.sharingSubMenu}
-
                         {isNovice ? null : this.filtersSubMenu}
-
                         {isNovice ? null : this.layoutSubMenu}
                     </div>
                 );
@@ -1549,7 +1548,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                     : PresBox.targetRenderedDoc(PresBox.Instance.activeItem)?.type;
                 return (
                     <div className="propertiesView" style={{ width: this.props.width }}>
-                        <div className="propertiesView-title" style={{ width: this.props.width }}>
+                        <div className="propertiesView-sectionTitle" style={{ width: this.props.width }}>
                             Presentation
                         </div>
                         <div className="propertiesView-name" style={{ borderBottom: 0 }}>
@@ -1564,7 +1563,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                                 <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresTransitions = !this.openPresTransitions))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
                                     &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Transitions
                                     <div className="propertiesView-presTrails-title-icon">
-                                        <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+                                        <FontAwesomeIcon icon={this.openPresTransitions ? 'caret-down' : 'caret-right'} size="lg"  />
                                     </div>
                                 </div>
                                 {this.openPresTransitions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.transitionDropdown}</div> : null}
@@ -1578,7 +1577,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                                     style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
                                     &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Visibilty
                                     <div className="propertiesView-presTrails-title-icon">
-                                        <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+                                        <FontAwesomeIcon icon={this.openPresVisibilityAndDuration ? 'caret-down' : 'caret-right'} size="lg"  />
                                     </div>
                                 </div>
                                 {this.openPresVisibilityAndDuration ? <div className="propertiesView-presTrails-content">{PresBox.Instance.visibiltyDurationDropdown}</div> : null}
@@ -1589,7 +1588,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                                 <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openPresProgressivize = !this.openPresProgressivize))} style={{ backgroundColor: this.openPresTransitions ? 'black' : '' }}>
                                     &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={'rocket'} /> &nbsp; Progressivize
                                     <div className="propertiesView-presTrails-title-icon">
-                                        <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+                                        <FontAwesomeIcon icon={this.openPresProgressivize ? 'caret-down' : 'caret-right'} size="lg"  />
                                     </div>
                                 </div>
                                 {this.openPresProgressivize ? <div className="propertiesView-presTrails-content">{PresBox.Instance.progressivizeDropdown}</div> : null}
@@ -1600,7 +1599,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                                 <div className="propertiesView-presTrails-title" onPointerDown={action(() => (this.openSlideOptions = !this.openSlideOptions))} style={{ backgroundColor: this.openSlideOptions ? 'black' : '' }}>
                                     &nbsp; <FontAwesomeIcon style={{ alignSelf: 'center' }} icon={type === DocumentType.AUDIO ? 'file-audio' : 'file-video'} /> &nbsp; {type === DocumentType.AUDIO ? 'Audio Options' : 'Video Options'}
                                     <div className="propertiesView-presTrails-title-icon">
-                                        <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg" color="white" />
+                                        <FontAwesomeIcon icon={this.openSlideOptions ? 'caret-down' : 'caret-right'} size="lg"  />
                                     </div>
                                 </div>
                                 {this.openSlideOptions ? <div className="propertiesView-presTrails-content">{PresBox.Instance.mediaOptionsDropdown}</div> : null}
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 96502115d..472eefa6a 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -160,7 +160,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 ''
             );
         case StyleProp.Color:
-            if (MainView.Instance.LastButton === doc) return Colors.DARK_GRAY;
+            if (MainView.Instance.LastButton === doc) return Doc.UserDoc().userBackgroundColor;
+            if (Doc.IsSystem(doc!)) return StrCast(Doc.UserDoc().userColor)
+            if (doc?.type === DocumentType.FONTICON) return Doc.UserDoc().userColor;
             const docColor: Opt<string> = StrCast(doc?.[fieldKey + 'color'], StrCast(doc?._color));
             if (docColor) return docColor;
             const docView = props?.DocumentView?.();
@@ -196,7 +198,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 ? 15
                 : 0;
         case StyleProp.BackgroundColor: {
-            if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
+            if (MainView.Instance.LastButton === doc) return StrCast(Doc.UserDoc().userColor); // hack to indicate active menu panel item
             let docColor: Opt<string> = StrCast(doc?.[fieldKey + '_backgroundColor'], StrCast(doc?._backgroundColor, isCaption ? 'rgba(0,0,0,0.4)' : ''));
             // prettier-ignore
             switch (doc?.type) {
@@ -221,9 +223,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
                 case DocumentType.COL:
                     if (StrCast(Doc.LayoutField(doc)).includes(SliderBox.name)) break;
                     docColor = docColor || (Doc.IsSystem(doc)
-                            ? darkScheme()
-                                ? undefined
-                                : undefined // system docs (seen in treeView) get a grayish background
+                            ? StrCast(Doc.UserDoc().userBackgroundColor)
                             : doc.annotationOn
                             ? '#00000010' // faint interior for collections on PDFs, images, etc
                             : doc?._isGroup
diff --git a/src/client/views/UndoStack.scss b/src/client/views/UndoStack.scss
index ab21e6d7e..192b99a12 100644
--- a/src/client/views/UndoStack.scss
+++ b/src/client/views/UndoStack.scss
@@ -2,9 +2,10 @@
     height: 100%;
     display: flex;
     flex-direction: column;
+    justify-content: center;
+    align-items: center;
     position: relative;
     pointer-events: all;
-    padding-left: 4px;
 }
 
 .undoStack-resultContainer {
@@ -21,9 +22,11 @@
 }
 
 .undoStack-commandsContainer {
-    background-color: whitesmoke;
     flex: 1 1 auto;
     overflow-y: scroll;
-    height: 30px;
+    height: fit-content;
+    width: 200px;
     border-radius: 5px;
+    padding: 5px;
+    max-height: 200px;
 }
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index f5af09e5b..28f1b8bd9 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -3,6 +3,9 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { UndoManager } from '../util/UndoManager';
 import './UndoStack.scss';
+import { StrCast } from '../../fields/Types';
+import { Doc } from '../../fields/Doc';
+import { Popup, Type } from 'browndash-components';
 
 interface UndoStackProps {
     width?: number;
@@ -15,32 +18,31 @@ export class UndoStack extends React.Component<UndoStackProps> {
     @observable static Expand: boolean;
     render() {
         return this.props.inline && UndoStack.HideInline ? null : (
-            <div
-                className="undoStack-outerContainer"
-                style={{ width: this.props.width, height: this.props.height ? (UndoStack.Expand ? 4 : 1) * this.props.height : undefined, top: UndoStack.Expand && this.props.height ? -this.props.height * 3 : undefined }}
-                onClick={action(e => (UndoStack.Expand = !UndoStack.Expand))}
-                onDoubleClick={action(e => (UndoStack.Expand = UndoStack.HideInline = false))}>
-                <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} style={{ background: UndoManager.batchCounter.get() ? 'yellow' : undefined }}>
-                    <div className="undoStack-resultContainer" key={0}>
-                        <div className="undoStack-commandString" style={{ fontWeight: 'bold', textAlign: 'center' }}>
-                            Undo/Redo Stack
-                        </div>
-                    </div>
-                    {UndoManager.undoStackNames.map((name, i) => (
-                        <div className="undoStack-resultContainer" key={i}>
-                            <div className="undoStack-commandString">{name.replace(/[^\.]*\./, '')}</div>
-                        </div>
-                    ))}
-                    {Array.from(UndoManager.redoStackNames)
-                        .reverse()
-                        .map((name, i) => (
+            <div className="undoStack-outerContainer">
+                <Popup 
+                    text={'Undo/Redo Stack'}
+                    color={StrCast(Doc.UserDoc().userVariantColor)}
+                    placement={`top-start`}
+                    type={Type.TERT}
+                    popup={
+                    <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} style={{ background: UndoManager.batchCounter.get() ? 'yellow' : undefined }}>
+                        {UndoManager.undoStackNames.map((name, i) => (
                             <div className="undoStack-resultContainer" key={i}>
-                                <div className="undoStack-commandString" style={{ fontWeight: 'bold', color: 'red' }}>
-                                    {name.replace(/[^\.]*\./, '')}
-                                </div>
+                                <div className="undoStack-commandString">{name.replace(/[^\.]*\./, '')}</div>
                             </div>
                         ))}
-                </div>
+                        {Array.from(UndoManager.redoStackNames)
+                            .reverse()
+                            .map((name, i) => (
+                                <div className="undoStack-resultContainer" key={i}>
+                                    <div className="undoStack-commandString" style={{ fontWeight: 'bold', color: 'red' }}>
+                                        {name.replace(/[^\.]*\./, '')}
+                                    </div>
+                                </div>
+                        ))}
+                    </div>    
+                    }
+                />
             </div>
         );
     }
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 9db8fe532..6eeccc94e 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -10,650 +10,13 @@
     border-bottom: $standard-border;
     padding: 0 10px;
     align-items: center;
+    overflow-x: scroll;
+    &::-webkit-scrollbar {
+        display: none;
+    }
 
-    .collectionMenu-hardCodedButton {
-        cursor: pointer;
-        color: $white;
-        width: 25px;
-        height: 25px;
-        padding: 5;
-        text-align: center;
+    .hardCodedButtons {
         display: flex;
-        justify-content: center;
-        align-items: center;
-        position: relative;
-        transition: 0.2s;
-        border-radius: 3px;
-
-        &:hover {
-            background-color: rgba(0, 0, 0, 0.2);
-        }
+        flex-direction: row;
     }
-}
-
-// .collectionMenu-cont {
-//     position: relative;
-//     display: inline-flex;
-//     width: 100%;
-//     opacity: 0.9;
-//     z-index: 901;
-//     transition: top .5s;
-//     background: $dark-gray;
-//     color: $white;
-//     transform-origin: top left;
-//     top: 0;
-//     width: 100%;
-
-//     .recordButtonOutline {
-//         border-radius: 100%;
-//         width: 18px;
-//         height: 18px;
-//         border: solid 1px $white;
-//         display: flex;
-//         align-items: center;
-//         justify-content: center;
-//     }
-
-//     .recordButtonInner {
-//         border-radius: 100%;
-//         width: 70%;
-//         height: 70%;
-//         background: $white;
-//     }
-
-//     .collectionMenu {
-//         display: flex;
-//         height: 100%;
-//         overflow: visible;
-//         z-index: 901;
-//         border: unset;
-
-//         .collectionMenu-divider {
-//             height: 100%;
-//             margin-left: 3px;
-//             margin-right: 3px;
-//             width: 2px;
-//             background-color: $medium-gray;
-//         }
-
-//         .collectionViewBaseChrome {
-//             display: flex;
-//             align-items: center;
-
-//             .collectionViewBaseChrome-viewPicker {
-//                 font-size: $small-text;
-//                 outline-color: $black;
-//                 color: $white;
-//                 border: none;
-//                 background: $dark-gray;               
-//             }
-
-//             .collectionViewBaseChrome-viewPicker:focus {
-//                 outline: none;
-//                 border: none;
-//             }
-
-//             .collectionViewBaseChrome-viewPicker:active {
-//                 outline-color: $black;
-//             }
-
-//             .collectionViewBaseChrome-button {
-//                 font-size: $small-text;
-//                 text-transform: uppercase;
-//                 letter-spacing: 2px;
-//                 background: $white;
-//                 color: $pink;
-//                 outline-color: $black;
-//                 border: none;
-//                 padding: 12px 10px 11px 10px;
-//                 margin-left: 10px;
-//             }
-
-//             .collectionViewBaseChrome-cmdPicker {
-//                 margin-left: 3px;
-//                 margin-right: 0px;
-//                 font-size: $small-text;
-//                 text-transform: capitalize;
-//                 color: $white;
-//                 border: none;
-//                 background: $dark-gray;     
-//             }
-
-//             .collectionViewBaseChrome-cmdPicker:focus {
-//                 border: none;
-//                 outline: none;
-//             }
-
-//             .commandEntry-outerDiv {
-//                 pointer-events: all;
-//                 background-color: transparent;
-//                 display: flex;
-//                 flex-direction: row;
-//                 align-items: center;
-//                 justify-content: center;
-//                 height: 100%;
-//                 overflow: hidden;
-
-//                 .commandEntry-drop {
-//                     color: $white;
-//                     width: 30px;
-//                     margin-top: auto;
-//                     margin-bottom: auto;
-//                 }
-//             }
-
-//             .commandEntry-outerDiv:hover{
-//                 background-color: $drop-shadow;
-
-//                 .collectionViewBaseChrome-viewPicker,
-//                 .collectionViewBaseChrome-cmdPicker{
-//                     background: $dark-gray;
-//                 }
-//             }
-
-//             .collectionViewBaseChrome-collapse {
-//                 transition: all .5s, opacity 0.3s;
-//                 position: absolute;
-//                 width: 30px;
-//                 transform-origin: top left;
-//                 pointer-events: all;
-//                 // margin-top: 10px;
-//             }
-
-//             @media only screen and (max-device-width: 480px) {
-//                 .collectionViewBaseChrome-collapse {
-//                     display: none;
-//                 }
-//             }
-
-//             .collectionViewBaseChrome-template,
-//             .collectionViewBaseChrome-viewModes {
-//                 align-items: center;
-//                 height: 100%;
-//                 display: flex;
-//                 background: transparent;
-//                 color: $medium-gray;
-//                 justify-content: center;
-//             }
-
-//             .collectionViewBaseChrome-viewSpecs {
-//                 margin-left: 5px;
-//                 display: grid;
-//                 border: none;
-//                 border-right: solid $medium-gray 1px;
-
-//                 .collectionViewBaseChrome-filterIcon {
-//                     position: relative;
-//                     display: flex;
-//                     margin: auto;
-//                     background: $dark-gray;
-//                     color: $white;
-//                     width: 30px;
-//                     height: 30px;
-//                     align-items: center;
-//                     justify-content: center;
-//                     border: none;
-//                     border-right: solid $medium-gray 1px;
-//                 }
-
-//                 .collectionViewBaseChrome-viewSpecsInput {
-//                     padding: 12px 10px 11px 10px;
-//                     border: 0px;
-//                     color: $medium-gray;
-//                     text-align: center;
-//                     letter-spacing: 2px;
-//                     outline-color: $black;
-//                     font-size: $small-text;
-//                     background: $white;
-//                     height: 100%;
-//                     width: 75px;
-//                 }
-
-//                 .collectionViewBaseChrome-viewSpecsMenu {
-//                     overflow: hidden;
-//                     transition: height .5s, display .5s;
-//                     position: absolute;
-//                     top: 60px;
-//                     z-index: 100;
-//                     display: flex;
-//                     flex-direction: column;
-//                     background: $white;
-//                     box-shadow: $medium-gray 2px 2px 4px;
-
-//                     .qs-datepicker {
-//                         left: unset;
-//                         right: 0;
-//                     }
-
-//                     .collectionViewBaseChrome-viewSpecsMenu-row {
-//                         display: grid;
-//                         grid-template-columns: 150px 200px 150px;
-//                         margin-top: 10px;
-//                         margin-right: 10px;
-
-//                         .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
-//                         .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
-//                         .collectionViewBaseChrome-viewSpecsMenu-rowRight {
-//                             font-size: $small-text;
-//                             letter-spacing: 2px;
-//                             color: $medium-gray;
-//                             margin-left: 10px;
-//                             padding: 5px;
-//                             border: none;
-//                             outline-color: $black;
-//                         }
-//                     }
-
-//                     .collectionViewBaseChrome-viewSpecsMenu-lastRow {
-//                         display: grid;
-//                         grid-template-columns: 1fr 1fr 1fr;
-//                         grid-gap: 10px;
-//                         margin: 10px;
-//                     }
-//                 }
-//             }
-//         }
-
-//         .collectionStackingViewChrome-cont,
-//         .collectionTreeViewChrome-cont,
-//         .collection3DCarouselViewChrome-cont {
-//             display: flex;
-//             justify-content: space-between;
-//         }
-
-//         .collectionGridViewChrome-cont {
-//             display: flex;
-//             margin-left: 10;
-
-//             .collectionGridViewChrome-viewPicker {
-//                 font-size: $small-text;
-//                 //text-transform: uppercase;
-//                 //letter-spacing: 2px;
-//                 background: $dark-gray;
-//                 color: $white;
-//                 outline-color: $black;
-//                 color: $white;
-//                 border: none;
-//                 border-right: solid $medium-gray 1px;
-//             }
-
-//             .collectionGridViewChrome-viewPicker:active {
-//                 outline-color: $black;
-//             }
-
-//             .grid-control {
-//                 align-self: center;
-//                 display: flex;
-//                 flex-direction: row;
-//                 margin-right: 5px;
-
-//                 .grid-icon {
-//                     margin-right: 5px;
-//                     align-self: center;
-//                 }
-
-//                 .flexLabel {
-//                     margin-bottom: 0;
-//                 }
-
-//                 .collectionGridViewChrome-entryBox {
-//                     width: 50%;
-//                     color: $black;
-//                 }
-
-//                 .collectionGridViewChrome-columnButton {
-//                     color: $black;
-//                 }
-//             }
-//         }
-
-//         .collectionStackingViewChrome-sort,
-//         .collectionTreeViewChrome-sort {
-//             display: flex;
-//             align-items: center;
-//             justify-content: space-between;
-
-//             .collectionStackingViewChrome-sortIcon,
-//             .collectionTreeViewChrome-sortIcon {
-//                 transition: transform .5s;
-//                 margin-left: 10px;
-//             }
-//         }
-
-//         button:hover {
-//             transform: scale(1);
-//         }
-
-
-//         .collectionStackingViewChrome-pivotField-cont,
-//         .collectionTreeViewChrome-pivotField-cont,
-//         .collection3DCarouselViewChrome-scrollSpeed-cont {
-//             justify-self: right;
-//             align-items: center;
-//             display: flex;
-//             grid-auto-columns: auto;
-//             font-size: $small-text;
-//             letter-spacing: 2px;
-
-//             .collectionStackingViewChrome-pivotField-label,
-//             .collectionTreeViewChrome-pivotField-label,
-//             .collection3DCarouselViewChrome-scrollSpeed-label {
-//                 grid-column: 1;
-//                 margin-right: 7px;
-//                 user-select: none;
-//                 font-family: $sans-serif;
-//                 letter-spacing: normal;
-//             }
-
-//             .collectionStackingViewChrome-sortIcon {
-//                 transition: transform .5s;
-//                 grid-column: 3;
-//                 text-align: center;
-//                 display: flex;
-//                 justify-content: center;
-//                 align-items: center;
-//                 cursor: pointer;
-//                 width: 25px;
-//                 height: 25px;
-//                 border-radius: 100%;
-//             }
-
-//             .collectionStackingViewChrome-sortIcon:hover {
-//                 background-color: $drop-shadow;
-//             }
-
-//             .collectionStackingViewChrome-pivotField,
-//             .collectionTreeViewChrome-pivotField,
-//             .collection3DCarouselViewChrome-scrollSpeed {
-//                 color: $white;
-//                 grid-column: 2;
-//                 grid-row: 1;
-//                 width: 90%;
-//                 min-width: 100px;
-//                 display: flex;
-//                 height: 80%;
-//                 border-radius: 7px;
-//                 align-items: center;
-//                 background: $white;
-
-//                 .editable-view-input,
-//                 input,
-//                 .editableView-container-editing-oneLine,
-//                 .editableView-container-editing {
-//                     margin: auto;
-//                     border: 0px;
-//                     color: $light-gray !important;
-//                     text-align: center;
-//                     letter-spacing: 2px;
-//                     outline-color: $black;
-//                     height: 100%;
-//                 }
-
-//                 .react-autosuggest__container {
-//                     margin: 0;
-//                     color: $medium-gray;
-//                     padding: 0px;
-//                 }
-//             }
-//         }
-
-//         .collectionStackingViewChrome-pivotField:hover,
-//         .collectionTreeViewChrome-pivotField:hover,
-//         .collection3DCarouselViewChrome-scrollSpeed:hover {
-//             cursor: text;
-//         }
-
-//     }
-// }
-
-// .collectionMenu-webUrlButtons {
-//     margin-left: 44;
-//     background: lightGray;
-//     display: flex;
-// }
-
-// .webBox-urlEditor {
-//     position: relative;
-//     opacity: 0.9;
-//     z-index: 901;
-//     transition: top .5s;
-
-//     .urlEditor {
-//         display: grid;
-//         grid-template-columns: 1fr auto;
-//         padding-bottom: 10px;
-//         overflow: hidden;
-//         margin-top: 5px;
-//         height: 35px;
-
-//         .editorBase {
-//             display: flex;
-
-//             .editor-collapse {
-//                 transition: all .5s, opacity 0.3s;
-//                 position: absolute;
-//                 width: 40px;
-//                 transform-origin: top left;
-//             }
-
-//             .switchToText {
-//                 color: $medium-gray;
-//             }
-
-//             .switchToText:hover {
-//                 color: $dark-gray;
-//             }
-//         }
-
-//         button:hover {
-//             transform: scale(1);
-//         }
-//     }
-// }
-
-// .collectionMenu-urlInput {
-//     padding: 12px 10px 11px 10px;
-//     border: 0px;
-//     color: $black;
-//     font-size: $small-text;
-//     letter-spacing: 2px;
-//     outline-color: $black;
-//     background: $white;
-//     width: 100%;
-//     min-width: 350px;
-//     margin-right: 10px;
-//     height: 100%;
-// }
-
-// .collectionFreeFormMenu-cont {
-//     display: inline-flex;
-//     position: relative;
-//     align-items: center;
-//     height: 100%;
-
-//     .color-previewI {
-//         width: 60%;
-//         top: 80%;
-//         position: absolute;
-//         height: 4px;
-//     }
-
-//     .color-previewII {
-//         width: 80%;
-//         height: 80%;
-//         margin-left: 10%;
-//         position: absolute;
-//         bottom: 5;
-//     }
-
-//     .btn-group {
-//         display: grid;
-//         grid-template-columns: auto auto auto auto;
-//         margin: auto;
-//         /* Make the buttons appear below each other */
-//     }
-
-//     .btn-draw {
-//         display: inline-flex;
-//         margin: auto;
-//         /* Make the buttons appear below each other */
-//     }
-
-//     .fwdKeyframe,
-//     .numKeyframe,
-//     .backKeyframe {
-//         cursor: pointer;
-//         position: relative;
-//         width: 20;
-//         height: 30;
-//         bottom: 0;
-//         background: $dark-gray;
-//         display: inline-flex;
-//         align-items: center;
-//         color: $white;
-//     }
-
-//     .backKeyframe {
-//         svg {
-//             display: block;
-//             margin: auto;
-//         }
-//     }
-
-
-//     .numKeyframe {
-//         flex-direction: column;
-//         padding-top: 5px;
-//     }
-
-//     .fwdKeyframe {
-//         svg {
-//             display: block;
-//             margin: auto;
-//         }
-
-//         border-right: solid $medium-gray 1px;
-//     }
-// }
-
-// .collectionSchemaViewChrome-cont {
-//     display: flex;
-//     font-size: $small-text;
-
-//     .collectionSchemaViewChrome-toggle {
-//         display: flex;
-//         margin-left: 10px;
-//     }
-
-//     .collectionSchemaViewChrome-label {
-//         text-transform: uppercase;
-//         letter-spacing: 2px;
-//         margin-right: 5px;
-//         display: flex;
-//         flex-direction: column;
-//         justify-content: center;
-//     }
-
-//     .collectionSchemaViewChrome-toggler {
-//         width: 100px;
-//         height: 35px;
-//         background-color: $black;
-//         position: relative;
-//     }
-
-//     .collectionSchemaViewChrome-togglerButton {
-//         width: 47px;
-//         height: 30px;
-//         background-color: $light-gray;
-//         // position: absolute;
-//         transition: all 0.5s ease;
-//         // top: 3px;
-//         margin-top: 3px;
-//         color: $medium-gray;
-//         letter-spacing: 2px;
-//         text-transform: uppercase;
-//         display: flex;
-//         flex-direction: column;
-//         justify-content: center;
-//         text-align: center;
-
-//         &.on {
-//             margin-left: 3px;
-//         }
-
-//         &.off {
-//             margin-left: 50px;
-//         }
-//     }
-// }
-
-
-// .commandEntry-outerDiv {
-//     display: flex;
-//     flex-direction: column;
-//     height: 40px;
-// }
-
-// .commandEntry-inputArea {
-//     display: flex;
-//     flex-direction: row;
-//     width: 150px;
-//     margin: auto auto auto auto;
-// }
-
-// .react-autosuggest__container {
-//     position: relative;
-//     width: 100%;
-//     margin-left: 5px;
-//     margin-right: 5px;
-// }
-
-// .react-autosuggest__input {
-//     border: 1px solid $light-gray;
-//     border-radius: 4px;
-//     width: 100%;
-// }
-
-// .react-autosuggest__input--focused {
-//     outline: none;
-// }
-
-// .react-autosuggest__input--open {
-//     border-bottom-left-radius: 0;
-//     border-bottom-right-radius: 0;
-// }
-
-// .react-autosuggest__suggestions-container {
-//     display: none;
-// }
-
-// .react-autosuggest__suggestions-container--open {
-//     display: block;
-//     position: fixed;
-//     overflow-y: auto;
-//     max-height: 400px;
-//     width: 180px;
-//     border: 1px solid $light-gray;
-//     background-color: $white;
-//     font-family: $sans-serif;
-//     font-weight: 300;
-//     font-size: $large-header;
-//     border-bottom-left-radius: 4px;
-//     border-bottom-right-radius: 4px;
-//     z-index: 2;
-// }
-
-// .react-autosuggest__suggestions-list {
-//     margin: 0;
-//     padding: 0;
-//     list-style-type: none;
-// }
-
-// .react-autosuggest__suggestion {
-//     cursor: pointer;
-//     padding: 10px 20px;
-// }
-
-// .react-autosuggest__suggestion--highlighted {
-//     background-color: $light-gray;
-// }
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 38692b924..9eb716763 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -2,23 +2,23 @@ import React = require('react');
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon, FontAwesomeIconProps } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@material-ui/core';
-import { action, computed, Lambda, observable, reaction, runInAction } from 'mobx';
+import { Toggle, ToggleType, Type } from 'browndash-components';
+import { Lambda, action, computed, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { ColorState } from 'react-color';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Document } from '../../../fields/documentSchemas';
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
 import { RichTextField } from '../../../fields/RichTextField';
 import { listSpec } from '../../../fields/Schema';
-import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
+import { Document } from '../../../fields/documentSchemas';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents, Utils } from '../../../Utils';
-import { Docs } from '../../documents/Documents';
 import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SelectionManager } from '../../util/SelectionManager';
@@ -28,21 +28,19 @@ import { undoBatch } from '../../util/UndoManager';
 import { AntimodeMenu } from '../AntimodeMenu';
 import { EditableView } from '../EditableView';
 import { GestureOverlay } from '../GestureOverlay';
-import { Colors } from '../global/globalEnums';
 import { ActiveFillColor, ActiveInkColor, SetActiveArrowEnd, SetActiveArrowStart, SetActiveBezierApprox, SetActiveFillColor, SetActiveInkColor, SetActiveInkWidth } from '../InkingStroke';
 import { LightboxView } from '../LightboxView';
+import { MainView } from '../MainView';
+import { DefaultStyleProvider } from '../StyleProvider';
 import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
 import { DocumentView, OpenWhereMod } from '../nodes/DocumentView';
-import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { RichTextMenu } from '../nodes/formattedText/RichTextMenu';
-import { DefaultStyleProvider } from '../StyleProvider';
 import { CollectionDockingView } from './CollectionDockingView';
-import { CollectionLinearView } from './collectionLinear';
 import './CollectionMenu.scss';
 import { COLLECTION_BORDER_WIDTH } from './CollectionView';
 import { TabDocView } from './TabDocView';
 import { CollectionFreeFormView } from './collectionFreeForm';
-import { Group, IconButton, Toggle, ToggleType, Type } from 'browndash-components';
+import { CollectionLinearView } from './collectionLinear';
 
 interface CollectionMenuProps {
     panelHeight: () => number;
@@ -96,6 +94,15 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
         }
     };
 
+    @action
+    toggleProperties = () => {
+        if (MainView.Instance.propertiesWidth() > 0) {
+            SettingsManager.propertiesWidth = 0;
+        } else {
+            SettingsManager.propertiesWidth = 300;
+        }
+    };
+
     buttonBarXf = () => {
         if (!this._docBtnRef.current) return Transform.Identity();
         const { scale, translateX, translateY } = Utils.GetScreenTransform(this._docBtnRef.current);
@@ -140,18 +147,30 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
     }
 
     render() {
-        const propIcon = SettingsManager.headerBarHeight > 0 ? 'angle-double-up' : 'angle-double-down';
-        const propTitle = SettingsManager.headerBarHeight > 0 ? 'Close Header Bar' : 'Open Header Bar';
+        const headerIcon = SettingsManager.headerBarHeight > 0 ? 'angle-double-up' : 'angle-double-down';
+        const headerTitle = SettingsManager.headerBarHeight > 0 ? 'Close Header Bar' : 'Open Header Bar';
+        const propIcon = SettingsManager.propertiesWidth > 0 ? 'angle-double-right' : 'angle-double-left';
+        const propTitle = SettingsManager.propertiesWidth > 0 ? 'Close Properties' : 'Open Properties';
 
         const hardCodedButtons = (
             <div className={`hardCodedButtons`}>
                 <Toggle 
                     toggleType={ToggleType.BUTTON} 
                     type={Type.PRIM} 
-                    color={Colors.LIGHT_GRAY} 
+                    color={StrCast(Doc.UserDoc().userColor)} 
                     onClick={this.toggleTopBar} 
                     toggleStatus={SettingsManager.headerBarHeight > 0} 
+                    icon={<FontAwesomeIcon icon={headerIcon} size="lg" />}
+                    tooltip={headerTitle}
+                />
+                <Toggle 
+                    toggleType={ToggleType.BUTTON} 
+                    type={Type.PRIM}
+                    color={StrCast(Doc.UserDoc().userColor)} 
+                    onClick={this.toggleProperties} 
+                    toggleStatus={SettingsManager.propertiesWidth > 0} 
                     icon={<FontAwesomeIcon icon={propIcon} size="lg" />}
+                    tooltip={propTitle}
                 />
             </div>
         );
@@ -159,7 +178,11 @@ export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
         // NEW BUTTONS
         //dash col linear view buttons
         const contMenuButtons = (
-            <div className="collectionMenu-container">
+            <div className="collectionMenu-container" 
+            style={{
+                background: StrCast(Doc.UserDoc().userBackgroundColor),
+                // borderColor: StrCast(Doc.UserDoc().userColor)
+            }} >
                 {this.contMenuButtons}
                 {hardCodedButtons}
             </div>
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 4cd3885f5..09be9dc76 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -386,6 +386,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
     @observable _headerHeight = 0;
     @computed get content() {
         const background = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.BackgroundColor);
+        const color = () => this.props.styleProvider?.(this.doc, this.props, StyleProp.Color);
         const pointerEvents = () => (this.props.isContentActive() === false ? 'none' : undefined);
         const titleBar = this.props.treeViewHideTitle || this.doc.treeViewHideTitle ? null : this.titleBar;
         return (
@@ -402,6 +403,7 @@ export class CollectionTreeView extends CollectionSubView<Partial<collectionTree
                     ref={r => !this.doc.treeViewHasOverlay && r && this.createTreeDropTarget(r)}
                     style={{
                         ...(!titleBar ? { marginLeft: this.marginX(), paddingTop: this.marginTop() } : {}),
+                        color: color(),
                         overflow: 'auto',
                         width: '100%',
                         height: '100%',
diff --git a/src/client/views/collections/TabDocView.scss b/src/client/views/collections/TabDocView.scss
index 58605c3f4..13bb3a577 100644
--- a/src/client/views/collections/TabDocView.scss
+++ b/src/client/views/collections/TabDocView.scss
@@ -65,11 +65,7 @@ input.lm_title {
 }
 
 .miniMap {
-    position: absolute;
     overflow: hidden;
-    right: 15;
-    bottom: 15;
-    border: solid 1px;
     width: 100%;
     height: 100%;
     transition: all 0.5s;
@@ -90,18 +86,5 @@ input.lm_title {
     cursor: pointer;
     position: absolute;
     bottom: 5;
-    display: flex;
     right: 5;
-    width: 25px;
-    height: 25px;
-    border-radius: 3px;
-    padding: 2px;
-    justify-content: center;
-    align-items: center;
-    align-content: center;
-    background-color: $light-gray;
-
-    &:hover {
-        box-shadow: none;
-    }
 }
diff --git a/src/client/views/collections/TabDocView.tsx b/src/client/views/collections/TabDocView.tsx
index 4d780f46b..714619a74 100644
--- a/src/client/views/collections/TabDocView.tsx
+++ b/src/client/views/collections/TabDocView.tsx
@@ -34,6 +34,7 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV
 import { CollectionView } from './CollectionView';
 import './TabDocView.scss';
 import React = require('react');
+import { Popup, Toggle, Type } from 'browndash-components';
 const _global = (window /* browser */ || global) /* node */ as any;
 
 interface TabDocViewProps {
@@ -573,63 +574,53 @@ export class TabMinimapView extends React.Component<TabMinimapViewProps> {
         const miniTop = 50 + ((NumCast(this.props.document._freeform_panY) - this.renderBounds.cy) / this.renderBounds.dim) * 100 - miniHeight / 2;
         const miniSize = this.returnMiniSize();
         return (
-            <>
-                {' '}
-                {this.props.document?.layout_hideMinimap ? null : (
-                    <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
-                        <CollectionFreeFormView
-                            Document={this.props.document}
-                            docViewPath={returnEmptyDoclist}
-                            childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
-                            noOverlay={true} // don't render overlay Docs since they won't scale
-                            setHeight={returnFalse}
-                            isContentActive={emptyFunction}
-                            isAnyChildContentActive={returnFalse}
-                            select={emptyFunction}
-                            isSelected={returnFalse}
-                            dontRegisterView={true}
-                            fieldKey={Doc.LayoutFieldKey(this.props.document)}
-                            bringToFront={emptyFunction}
-                            rootSelected={returnTrue}
-                            addDocument={returnFalse}
-                            moveDocument={returnFalse}
-                            removeDocument={returnFalse}
-                            PanelWidth={this.returnMiniSize}
-                            PanelHeight={this.returnMiniSize}
-                            ScreenToLocalTransform={Transform.Identity}
-                            renderDepth={0}
-                            whenChildContentsActiveChanged={emptyFunction}
-                            focus={emptyFunction}
-                            styleProvider={TabMinimapView.miniStyleProvider}
-                            addDocTab={this.props.addDocTab}
-                            pinToPres={TabDocView.PinDoc}
-                            childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
-                            childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
-                            searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
-                            fitContentsToBox={returnTrue}
-                        />
-                        <div className="miniOverlay" onPointerDown={this.miniDown}>
-                            <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
+            <div className="miniMap-hidden">
+                <Popup
+                    icon={<FontAwesomeIcon icon="globe-asia" size="lg" />}
+                    color={StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}
+                    type={Type.TERT}
+                    onPointerDown={e => e.stopPropagation()}
+                    placement={'top-end'}
+                    popup={
+                        <div className="miniMap" style={{ width: miniSize, height: miniSize, background: this.props.background() }}>
+                            <CollectionFreeFormView
+                                Document={this.props.document}
+                                docViewPath={returnEmptyDoclist}
+                                childLayoutTemplate={this.childLayoutTemplate} // bcz: Ugh .. should probably be rendering a CollectionView or the minimap should be part of the collectionFreeFormView to avoid having to set stuff like this.
+                                noOverlay={true} // don't render overlay Docs since they won't scale
+                                setHeight={returnFalse}
+                                isContentActive={emptyFunction}
+                                isAnyChildContentActive={returnFalse}
+                                select={emptyFunction}
+                                isSelected={returnFalse}
+                                dontRegisterView={true}
+                                fieldKey={Doc.LayoutFieldKey(this.props.document)}
+                                bringToFront={emptyFunction}
+                                rootSelected={returnTrue}
+                                addDocument={returnFalse}
+                                moveDocument={returnFalse}
+                                removeDocument={returnFalse}
+                                PanelWidth={this.returnMiniSize}
+                                PanelHeight={this.returnMiniSize}
+                                ScreenToLocalTransform={Transform.Identity}
+                                renderDepth={0}
+                                whenChildContentsActiveChanged={emptyFunction}
+                                focus={emptyFunction}
+                                styleProvider={TabMinimapView.miniStyleProvider}
+                                addDocTab={this.props.addDocTab}
+                                pinToPres={TabDocView.PinDoc}
+                                childFilters={CollectionDockingView.Instance?.childDocFilters ?? returnEmptyDoclist}
+                                childFiltersByRanges={CollectionDockingView.Instance?.childDocRangeFilters ?? returnEmptyDoclist}
+                                searchFilterDocs={CollectionDockingView.Instance?.searchFilterDocs ?? returnEmptyDoclist}
+                                fitContentsToBox={returnTrue}
+                            />
+                            <div className="miniOverlay" onPointerDown={this.miniDown}>
+                                <div className="miniThumb" style={{ width: `${miniWidth}% `, height: `${miniHeight}% `, left: `${miniLeft}% `, top: `${miniTop}% ` }} />
+                            </div>
                         </div>
-                    </div>
-                )}
-                <Tooltip key="ttip" title={<div className="dash-tooltip">{this.props.document.layout_hideMinimap ? 'Open minimap' : 'Close minimap'}</div>}>
-                    <div
-                        className="miniMap-hidden"
-                        style={{
-                            color: this.props.document.layout_hideMinimap ? Colors.BLACK : Colors.WHITE,
-                            backgroundColor: this.props.document.layout_hideMinimap ? Colors.LIGHT_GRAY : Colors.MEDIUM_BLUE,
-                            boxShadow: this.props.document.layout_hideMinimap ? Shadows.STANDARD_SHADOW : undefined,
-                        }}
-                        onPointerDown={e => e.stopPropagation()}
-                        onClick={action(e => {
-                            e.stopPropagation();
-                            this.props.document!.layout_hideMinimap = !this.props.document!.layout_hideMinimap;
-                        })}>
-                        <FontAwesomeIcon icon="globe-asia" size="lg" />
-                    </div>
-                </Tooltip>
-            </>
+                    }
+                />
+            </div>
         );
     }
 }
diff --git a/src/client/views/collections/TreeView.scss b/src/client/views/collections/TreeView.scss
index 7eab03e1d..85f99b9c2 100644
--- a/src/client/views/collections/TreeView.scss
+++ b/src/client/views/collections/TreeView.scss
@@ -24,34 +24,18 @@
         // width: $TREE_BULLET_WIDTH;
         width: 100%;
         height: 100%;
-        position: absolute;
-
-        .treeView-expandIcon {
-            display: none;
-            left: -10px;
-            position: absolute;
-        }
-
-        .treeView-checkIcon {
-            left: 3.5px;
-            top: 2px;
-            position: absolute;
-        }
-
-        &:hover {
-            .treeView-expandIcon {
-                display: unset;
-            }
-        }
+        position: relative;
+        display: flex;
+        flex-direction: row;
     }
 
-    .treeView-bulletIcons:hover img {
-        left: 14px;
-        position: absolute;
-        transform-origin: center left;
-        transform: scale(6);
-        pointer-events: none;
-    }
+    // .treeView-bulletIcons:hover img {
+    //     left: 14px;
+    //     position: absolute;
+    //     transform-origin: center left;
+    //     transform: scale(6);
+    //     pointer-events: none;
+    // }
 
     .bullet {
         grid-column: 1;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 8d8d895c6..55f62cdf2 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -34,6 +34,7 @@ import { CollectionTreeView, TreeViewType } from './CollectionTreeView';
 import { CollectionView } from './CollectionView';
 import './TreeView.scss';
 import React = require('react');
+import { IconButton, Size } from 'browndash-components';
 
 export interface TreeViewProps {
     treeView: CollectionTreeView;
@@ -541,6 +542,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         TraceMobx();
         const expandKey = this.treeViewExpandedView;
         const sortings = (this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewSortings) as { [key: string]: { color: string; label: string } }) ?? {};
+        const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color)
+        console.log("tree view", color, this.doc.title, Doc.IsSystem(this.doc))
         if (['links', 'annotations', 'embeddings', this.fieldKey].includes(expandKey)) {
             const sorting = StrCast(this.doc.treeViewSortCriterion, TreeSort.None);
             const sortKeys = Object.keys(sortings);
@@ -580,7 +583,9 @@ export class TreeView extends React.Component<TreeViewProps> {
                 );
             }
             return (
-                <>
+                <div style={{ 
+                    color: color
+                 }}>
                     {!docs?.length || this.props.AddToMap /* hack to identify pres box trees */ ? null : (
                         <div className={'treeView-sorting'} style={{ background: sortings[sorting]?.color }}>
                             {sortings[sorting]?.label}
@@ -640,17 +645,18 @@ export class TreeView extends React.Component<TreeViewProps> {
                                   this._renderCount
                               )}
                     </ul>
-                </>
+                </div>
             );
         } else if (this.treeViewExpandedView === 'fields') {
             return (
-                <ul key={this.doc[Id] + this.doc.title} style={{ cursor: 'inherit' }}>
+                <ul key={this.doc[Id] + this.doc.title} style={{ cursor: 'inherit', color: color }}>
                     <div>{this.expandedField}</div>
                 </ul>
             );
         }
         return (
             <ul
+                style={{ color: color }}
                 onPointerDown={e => {
                     e.preventDefault();
                     e.stopPropagation();
@@ -685,6 +691,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get renderBullet() {
         TraceMobx();
         const iconType = this.props.treeView.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.TreeViewIcon + (this.treeViewOpen ? ':open' : !this.childDocs.length ? ':empty' : '')) || 'question';
+        const color = this.props.styleProvider?.(this.doc, this.props.treeView.props, StyleProp.Color)
         const checked = this.onCheckedClick ? this.doc.treeViewChecked ?? 'unchecked' : undefined;
         return (
             <div
@@ -705,14 +712,26 @@ export class TreeView extends React.Component<TreeViewProps> {
                 }>
                 {this.props.treeView.outlineMode ? (
                     !(this.doc.text as RichTextField)?.Text ? null : (
-                        <FontAwesomeIcon size="sm" icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />
+                        <IconButton
+                            color={color} 
+                            icon={<FontAwesomeIcon icon={[this.childDocs?.length && !this.treeViewOpen ? 'fas' : 'far', 'circle']} />}
+                            size={Size.XSMALL}
+                        />
                     )
                 ) : (
                     <div className="treeView-bulletIcons" style={{ color: Doc.IsSystem(DocCast(this.doc.proto)) ? 'red' : undefined }}>
-                        <div className={`treeView-${this.onCheckedClick ? 'checkIcon' : 'expandIcon'}`}>
-                            <FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />
-                        </div>
-                        {this.onCheckedClick ? null : typeof iconType === 'string' ? <FontAwesomeIcon icon={iconType as IconProp} /> : iconType}
+                        <IconButton
+                            color={color} 
+                            icon={<FontAwesomeIcon size="sm" icon={checked === 'check' ? 'check' : checked === 'x' ? 'times' : checked === 'unchecked' ? 'square' : !this.treeViewOpen ? 'caret-right' : 'caret-down'} />}
+                            size={Size.XSMALL}
+                        />
+                        {this.onCheckedClick ? null : 
+                        <IconButton
+                            color={color} 
+                            icon={<FontAwesomeIcon icon={iconType as IconProp} />}
+                            size={Size.XSMALL}
+                        />
+                        }
                     </div>
                 )}
             </div>
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
index c9168d40a..0f51fe6ff 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeOptionsMenu.tsx
@@ -4,6 +4,10 @@ import { Tooltip } from '@material-ui/core';
 import { observer } from 'mobx-react';
 import { unimplementedFunction } from '../../../../Utils';
 import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { IconButton } from 'browndash-components';
+import { StrCast } from '../../../../fields/Types';
+import { Doc } from '../../../../fields/Doc';
+import { computed } from 'mobx';
 
 @observer
 export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -22,39 +26,44 @@ export class MarqueeOptionsMenu extends AntimodeMenu<AntimodeMenuProps> {
         MarqueeOptionsMenu.Instance = this;
     }
 
+    @computed get userColor() {
+        return StrCast(Doc.UserDoc().userColor)
+    }
+
     render() {
-        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ margin: 'auto', width: 19, transform: 'translate(-2px, -2px)' }} />;
+        const presPinWithViewIcon = <img src="/assets/pinWithView.png" style={{ width: 19 }} />;
         const buttons = (
             <>
-                <Tooltip key="collect" title={<div className="dash-tooltip">Create a Collection</div>} placement="bottom">
-                    <button className="antimodeMenu-button" onPointerDown={this.createCollection}>
-                        <FontAwesomeIcon icon="object-group" size="lg" />
-                    </button>
-                </Tooltip>
-                ,
-                <Tooltip key="group" title={<div className="dash-tooltip">Create a Grouping</div>} placement="bottom">
-                    <button className="antimodeMenu-button" onPointerDown={e => this.createCollection(e, true)}>
-                        <FontAwesomeIcon icon="layer-group" size="lg" />
-                    </button>
-                </Tooltip>
-                ,
-                <Tooltip key="summarize" title={<div className="dash-tooltip">Summarize Documents</div>} placement="bottom">
-                    <button className="antimodeMenu-button" onPointerDown={this.summarize}>
-                        <FontAwesomeIcon icon="compress-arrows-alt" size="lg" />
-                    </button>
-                </Tooltip>
-                ,
-                <Tooltip key="delete" title={<div className="dash-tooltip">Delete Documents</div>} placement="bottom">
-                    <button className="antimodeMenu-button" onPointerDown={this.delete}>
-                        <FontAwesomeIcon icon="trash-alt" size="lg" />
-                    </button>
-                </Tooltip>
-                ,
-                <Tooltip key="pinWithView" title={<div className="dash-tooltip">Pin selected region to trail</div>} placement="bottom">
-                    <button className="antimodeMenu-button" onPointerDown={this.pinWithView}>
-                        {presPinWithViewIcon}
-                    </button>
-                </Tooltip>
+                <IconButton 
+                    tooltip={"Create a Collection"}
+                    onPointerDown={this.createCollection}
+                    icon={<FontAwesomeIcon icon="object-group"/>}
+                    color={this.userColor}
+                />
+                <IconButton 
+                    tooltip={"Create a Grouping"}
+                    onPointerDown={e => this.createCollection(e, true)}
+                    icon={<FontAwesomeIcon icon="layer-group"/>}
+                    color={this.userColor}
+                />
+                <IconButton 
+                    tooltip={"Summarize Documents"}
+                    onPointerDown={this.summarize}
+                    icon={<FontAwesomeIcon icon="compress-arrows-alt"/>}
+                    color={this.userColor}
+                />
+                <IconButton 
+                    tooltip={"Delete Documents"}
+                    onPointerDown={this.delete}
+                    icon={<FontAwesomeIcon icon="trash-alt"/>}
+                    color={this.userColor}
+                />
+                <IconButton 
+                    tooltip={"Pin selected region"}
+                    onPointerDown={this.pinWithView}
+                    icon={presPinWithViewIcon}
+                    color={this.userColor}
+                />
             </>
         );
         return this.getElement(buttons);
diff --git a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
index 446e720e8..56b8366d0 100644
--- a/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
+++ b/src/client/views/collections/collectionLinear/CollectionLinearView.tsx
@@ -20,7 +20,8 @@ import { UndoStack } from '../../UndoStack';
 import { CollectionStackedTimeline } from '../CollectionStackedTimeline';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionLinearView.scss';
-import { Button, Type } from 'browndash-components';
+import { Button, Toggle, ToggleType, Type } from 'browndash-components';
+import { Colors } from '../../global/globalEnums';
 
 /**
  * CollectionLinearView is the class for rendering the horizontal collection
@@ -47,7 +48,7 @@ export class CollectionLinearView extends CollectionSubView() {
 
     componentDidMount() {
         this._widthDisposer = reaction(
-            () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsExpanded ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[Width]() || this.dimension()) + tot + 4, 0) : 0),
+            () => 5 + NumCast(this.rootDoc.linearBtnWidth, this.dimension()) + (this.layoutDoc.linearView_IsOpen ? this.childDocs.filter(doc => !doc.hidden).reduce((tot, doc) => (doc[Width]() || this.dimension()) + tot + 4, 0) : 0),
             width => this.childDocs.length && (this.layoutDoc._width = width),
             { fireImmediately: true }
         );
@@ -199,36 +200,48 @@ export class CollectionLinearView extends CollectionSubView() {
     render() {
         const flexDir = StrCast(this.Document.flexDirection); // Specify direction of linear view content
         const flexGap = NumCast(this.Document.flexGap); // Specify the gap between linear view content
-        const isExpanded = BoolCast(this.layoutDoc.linearView_IsExpanded);
+        const isExpanded = BoolCast(this.layoutDoc.linearView_IsOpen);
 
         const menuOpener = (
-            <Button 
+            <Toggle
                 text={Cast(this.props.Document.icon, 'string', null)} 
-                icon={<FontAwesomeIcon icon={isExpanded ? 'minus' : 'plus'} />}
+                icon={Cast(this.props.Document.icon, 'string', null) ? undefined : <FontAwesomeIcon icon={isExpanded ? 'minus' : 'plus'} />}
                 type={Type.TERT}
+                color={StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}
                 onPointerDown={e => e.stopPropagation()}
+                toggleType={ToggleType.BUTTON}
+                toggleStatus={BoolCast(this.layoutDoc.linearView_IsOpen)}
                 onClick={() => {
-                        this.layoutDoc.linearView_IsExpanded = !isExpanded;
+                        this.layoutDoc.linearView_IsOpen = !isExpanded;
                 }}
                 tooltip={isExpanded ? 'Close' : 'Open'}
+                fillWidth={true}
+                align={'center'}
             />
         );
 
         return (
-            <div className={`collectionLinearView-outer ${this.layoutDoc.linearView_SubMenu}`} style={{ backgroundColor: this.layoutDoc.linearView_IsExpanded ? undefined : 'transparent' }}>
+            <div className={`collectionLinearView-outer ${this.layoutDoc.linearView_SubMenu}`} style={{ backgroundColor: this.layoutDoc.linearView_IsOpen ? undefined : 'transparent' }}>
                 <div className="collectionLinearView" ref={this.createDashEventsTarget} onContextMenu={this.myContextMenu} style={{ minHeight: this.dimension(), pointerEvents: 'all' }}>
-                    {!this.props.Document.linearView_Expandable ? null : menuOpener}
-                    {!this.layoutDoc.linearView_IsExpanded ? null : (
-                        <div
-                            className="collectionLinearView-content"
-                            style={{
-                                height: this.dimension(),
-                                flexDirection: flexDir as any,
-                                gap: flexGap,
-                            }}>
-                            {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
-                        </div>
-                    )}
+                    {this.props.Document.linearView_Dropdown ? 
+                        <div>Hello World!</div>
+                        : 
+                        <>
+                        {!this.props.Document.linearView_Expandable ? null : menuOpener}
+                        {!this.layoutDoc.linearView_IsOpen ? null : (
+                            <div
+                                className="collectionLinearView-content"
+                                style={{
+                                    height: this.dimension(),
+                                    flexDirection: flexDir as any,
+                                    gap: flexGap,
+                                }}>
+                                {this.childLayoutPairs.map(pair => this.getDisplayDoc(pair.layout))}
+                            </div>
+                        )}
+                        </>
+                    }
+                    
                 </div>
             </div>
         );
diff --git a/src/client/views/global/globalScripts.ts b/src/client/views/global/globalScripts.ts
index 8f6d898fe..d22b6b4d9 100644
--- a/src/client/views/global/globalScripts.ts
+++ b/src/client/views/global/globalScripts.ts
@@ -66,19 +66,20 @@ ScriptingGlobals.add(function setBackgroundColor(color?: string, checkResult?: b
 // toggle: Set overlay status of selected document
 ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boolean) {
     if (checkResult) {
-        return Doc.SharingDoc().userColor;
+        return Doc.SharingDoc().headingColor;
     }
-    Doc.SharingDoc().userColor = undefined;
-    Doc.GetProto(Doc.SharingDoc()).userColor = color;
+    Doc.SharingDoc().headingColor = undefined;
+    Doc.GetProto(Doc.SharingDoc()).headingColor = color;
     Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'author_date');
 });
 
 // toggle: Set overlay status of selected document
 ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
+    console.log(checkResult);
     const selected = SelectionManager.Views().length ? SelectionManager.Views()[0] : undefined;
     if (checkResult) {
-        if (NumCast(selected?.Document.z) >= 1) return Colors.MEDIUM_BLUE;
-        return 'transparent';
+        if (NumCast(selected?.Document.z) >= 1) return true;
+        return false;
     }
     selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
 });
@@ -88,45 +89,47 @@ ScriptingGlobals.add(function showFreeform(attr: 'flashcards' | 'grid' | 'snapli
     // prettier-ignore
     const map: Map<'flashcards' | 'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll', { waitForRender?: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([
         ['grid', {
-            checkResult: (doc:Doc) => doc._freeform_backgroundGrid,
+            checkResult: (doc:Doc) => BoolCast(doc._freeform_backgroundGrid, false),
             setDoc: (doc:Doc) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
         }],
         ['snaplines', {
-            checkResult: (doc:Doc) => doc._freeform_snapLines,
+            checkResult: (doc:Doc) => BoolCast(doc._freeform_snapLines, false),
             setDoc: (doc:Doc) => doc._freeform_snapLines = !doc._freeform_snapLines,
         }],
         ['viewAll', {
-            checkResult: (doc:Doc) => doc._freeform_fitContentsToBox,
+            checkResult: (doc:Doc) => BoolCast(doc._freeform_fitContentsToBox, false),
             setDoc: (doc:Doc) => doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox,
         }],
         ['clusters', {
             waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
-            checkResult: (doc:Doc) => doc._freeform_useClusters,
+            checkResult: (doc:Doc) => BoolCast(doc._freeform_useClusters, false),
             setDoc: (doc:Doc) => doc._freeform_useClusters = !doc._freeform_useClusters,
         }],
         ['arrange', {
             waitForRender: true, // flags that undo batch should terminate after a re-render giving the script the chance to fire
-            checkResult: (doc:Doc) => doc._autoArrange,
+            checkResult: (doc:Doc) => BoolCast(doc._autoArrange, false),
             setDoc: (doc:Doc) => doc._autoArrange = !doc._autoArrange,
         }],
         ['flashcards', {
-            checkResult: (doc:Doc) => Doc.UserDoc().defaultToFlashcards,
+            checkResult: (doc:Doc) => BoolCast(Doc.UserDoc().defaultToFlashcards, false),
             setDoc: (doc:Doc) => Doc.UserDoc().defaultToFlashcards = !Doc.UserDoc().defaultToFlashcards,
         }],
    ]);
 
     if (checkResult) {
-        return map.get(attr)?.checkResult(selected) ? Colors.MEDIUM_BLUE : 'transparent';
+        console.log(attr, map.get(attr)?.checkResult(selected))
+        return map.get(attr)?.checkResult(selected);
     }
     const batch = map.get(attr)?.waitForRender ? UndoManager.StartBatch('set freeform attribute') : { end: () => {} };
     SelectionManager.Docs().map(dv => map.get(attr)?.setDoc(dv));
     setTimeout(() => batch.end(), 100);
 });
-ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize', value: any, checkResult?: boolean) {
+
+ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highlight' | 'fontSize' | 'alignment', value: any, checkResult?: boolean) {
     const editorView = RichTextMenu.Instance?.TextView?.EditorView;
     const selected = SelectionManager.Docs().lastElement();
     // prettier-ignore
-    const map: Map<'font'|'fontColor'|'highlight'|'fontSize', { checkResult: () => any; setDoc: () => void;}> = new Map([
+    const map: Map<'font'|'fontColor'|'highlight'|'fontSize'|'alignment', { checkResult: () => any; setDoc: () => void;}> = new Map([
         ['font', {
             checkResult: () => RichTextMenu.Instance?.fontFamily,
             setDoc: () => value && RichTextMenu.Instance.setFontFamily(value),
@@ -139,6 +142,10 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
             checkResult: () => RichTextMenu.Instance?.fontColor,
             setDoc: () => value && RichTextMenu.Instance.setColor(value),
         }],
+        ['alignment', {
+            checkResult: () => RichTextMenu.Instance.textAlign,
+            setDoc: () => value && editorView?.state ? RichTextMenu.Instance.align(editorView, editorView.dispatch, value):(Doc.UserDoc().textAlign = value),
+        }],
         ['fontSize', {
             checkResult: () => RichTextMenu.Instance?.fontSize.replace('px', ''),
             setDoc: () => {
@@ -157,6 +164,7 @@ ScriptingGlobals.add(function setFontAttr(attr: 'font' | 'fontColor' | 'highligh
 
 type attrname = 'noAutoLink' | 'dictation' | 'bold' | 'italics' | 'underline' | 'left' | 'center' | 'right' | 'bullet' | 'decimal';
 type attrfuncs = [attrname, { checkResult: () => boolean; toggle: () => any }];
+
 ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?: boolean) {
     const textView = RichTextMenu.Instance?.TextView;
     const editorView = textView?.EditorView;
@@ -182,7 +190,10 @@ ScriptingGlobals.add(function toggleCharStyle(charStyle: attrname, checkResult?:
                         toggle: editorView ? RichTextMenu.Instance.toggleUnderline : () => (Doc.UserDoc().textDecoration = Doc.UserDoc().textDecoration === 'underline' ? undefined : 'underline') }]]
 
     const map = new Map(attrs.concat(alignments).concat(listings));
-    if (checkResult) return map.get(charStyle)?.checkResult() ? Colors.MEDIUM_BLUE : 'transparent';
+    if (checkResult) {
+        console.log(charStyle, checkResult, map.get(charStyle)?.checkResult());
+        return map.get(charStyle)?.checkResult();
+    }
     map.get(charStyle)?.toggle();
 });
 
@@ -270,9 +281,9 @@ function setActiveTool(tool: InkTool | GestureUtils.Gestures, keepPrim: boolean,
     if (checkResult) {
         return (Doc.ActiveTool === tool && !GestureOverlay.Instance?.InkShape) || GestureOverlay.Instance?.InkShape === tool
             ? GestureOverlay.Instance?.KeepPrimitiveMode || ![GestureUtils.Gestures.Circle, GestureUtils.Gestures.Line, GestureUtils.Gestures.Rectangle].includes(tool as GestureUtils.Gestures)
-                ? Colors.MEDIUM_BLUE
-                : Colors.MEDIUM_BLUE_ALT
-            : 'transparent';
+                ? true
+                : true
+            : false;
     }
     runInAction(() => {
         if (GestureOverlay.Instance) {
@@ -308,7 +319,7 @@ ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | '
     // prettier-ignore
     const map: Map<'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
         ['inkMask', {
-            checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask()) ? Colors.MEDIUM_BLUE : 'transparent'),
+            checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask())),
             setInk: (doc: Doc) => (doc.stroke_isInkMask = !doc.stroke_isInkMask),
             setMode: () => selected?.type !== DocumentType.INK && SetActiveIsInkMask(!ActiveIsInkMask()),
         }],
diff --git a/src/client/views/linking/LinkPopup.scss b/src/client/views/linking/LinkPopup.scss
index b20ad9476..4bfb4b0b9 100644
--- a/src/client/views/linking/LinkPopup.scss
+++ b/src/client/views/linking/LinkPopup.scss
@@ -4,7 +4,6 @@
     top: 0;
     height: 200px;
     width: 200px;
-    position: absolute;
     // padding: 15px;
     border-radius: 3px;
 
@@ -37,8 +36,4 @@
             margin: auto;
         }
     }
-
-    .searchBox-container {
-        background: pink;
-    }
 }
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index 745efea08..6895c0746 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -14,7 +14,6 @@ import React = require('react');
 import { OpenWhere } from '../nodes/DocumentView';
 
 interface LinkPopupProps {
-    showPopup: boolean;
     linkFrom?: () => Doc | undefined;
     linkCreateAnchor?: () => Doc | undefined;
     linkCreated?: (link: Doc) => void;
@@ -44,10 +43,9 @@ export class LinkPopup extends React.Component<LinkPopupProps> {
     getPHeight = () => 500;
 
     render() {
-        const popupVisibility = this.props.showPopup ? 'block' : 'none';
         const linkDoc = this.props.linkFrom ? this.props.linkFrom : undefined;
         return (
-            <div className="linkPopup-container" style={{ display: popupVisibility }}>
+            <div className="linkPopup-container">
                 {/* <div className="linkPopup-url-container">
                     <input autoComplete="off" type="text" value={this.linkURL} placeholder="Enter URL..." onChange={this.onLinkChange} />
                     <button onPointerDown={e => this.makeLinkToURL(this.linkURL, "add:right")}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e954d0484..7e8eef0a5 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -18,7 +18,7 @@ import { SearchBox } from '../search/SearchBox';
 import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
 import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
 import { AudioBox } from './AudioBox';
-import { FontIconBox } from './button/FontIconBox';
+import { FontIconBox } from './FontIconBox/FontIconBox';
 import { ColorBox } from './ColorBox';
 import { ComparisonBox } from './ComparisonBox';
 import { DataVizBox } from './DataVizBox/DataVizBox';
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 8a35ca2a4..0b8ea1150 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1111,8 +1111,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
         );
         const targetDoc = layout_showTitle?.startsWith('_') ? this.layoutDoc : this.rootDoc;
         const background = StrCast(
-            SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.userColor,
-            Doc.UserDoc().layout_showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().userColor) : 'rgba(0,0,0,0.4)'
+            SharingManager.Instance.users.find(u => u.user.email === this.dataDoc.author)?.sharingDoc.headingColor,
+            Doc.UserDoc().layout_showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().headingColor) : 'rgba(0,0,0,0.4)'
         );
         const layout_sidebarWidthPercent = +StrCast(this.layoutDoc.layout_sidebarWidthPercent).replace('%', '');
         const titleView = !layout_showTitle ? null : (
diff --git a/src/client/views/nodes/FontIconBox/ButtonInterface.ts b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
new file mode 100644
index 000000000..0aa2ac8e1
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/ButtonInterface.ts
@@ -0,0 +1,12 @@
+import { Doc } from "../../../../fields/Doc";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { ButtonType } from "./FontIconBox";
+
+export interface IButtonProps {
+    type: string | ButtonType;
+    rootDoc: Doc;
+    label: any;
+    icon: IconProp;
+    color: string;
+    backgroundColor: string;
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox/FontIconBadge.scss b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
new file mode 100644
index 000000000..78f506e57
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBadge.scss
@@ -0,0 +1,11 @@
+.fontIconBadge {
+    background: red;
+    width: 15px;
+    height: 15px;
+    top: 8px;
+    display: block;
+    position: absolute;
+    right: 5;
+    border-radius: 50%;
+    text-align: center;
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/FontIconBox/FontIconBadge.tsx b/src/client/views/nodes/FontIconBox/FontIconBadge.tsx
new file mode 100644
index 000000000..b50588ce2
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBadge.tsx
@@ -0,0 +1,37 @@
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import './FontIconBadge.scss';
+
+interface FontIconBadgeProps {
+    value: string | undefined;
+}
+
+@observer
+export class FontIconBadge extends React.Component<FontIconBadgeProps> {
+    _notifsRef = React.createRef<HTMLDivElement>();
+
+    // onPointerDown = (e: React.PointerEvent) => {
+    //     setupMoveUpEvents(this, e,
+    //         (e: PointerEvent) => {
+    //             const dragData = new DragManager.DocumentDragData([this.props.collection!]);
+    //             DragManager.StartDocumentDrag([this._notifsRef.current!], dragData, e.x, e.y);
+    //             return true;
+    //         },
+    //         returnFalse, emptyFunction, false);
+    // }
+
+    render() {
+        if (this.props.value === undefined) return null;
+        return (
+            <div className="fontIconBadge-container" ref={this._notifsRef}>
+                <div
+                    className="fontIconBadge"
+                    style={{ display: 'initial' }}
+                    // onPointerDown={this.onPointerDown}
+                >
+                    {this.props.value}
+                </div>
+            </div>
+        );
+    }
+}
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.scss b/src/client/views/nodes/FontIconBox/FontIconBox.scss
new file mode 100644
index 000000000..9d9fa26b0
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.scss
@@ -0,0 +1,438 @@
+@import '../../global/globalCssVariables';
+
+.menuButton {
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    font-size: 80%;
+    border-radius: $standard-border-radius;
+    transition: 0.15s;
+
+    .menuButton-wrap {
+        grid-column: 1;
+        justify-content: center;
+        align-items: center;
+        text-align: center;
+    }
+
+    .fontIconBox-label {
+        color: $white;
+        bottom: -1;
+        position: absolute;
+        text-align: center;
+        font-size: 7px;
+        letter-spacing: normal;
+        background-color: inherit;
+        border-radius: 8px;
+        padding: 0;
+        width: 100%;
+        font-family: 'system-ui';
+        text-transform: uppercase;
+        font-weight: bold;
+        transition: 0.15s;
+    }
+
+    .fontIconBox-icon {
+        width: 80%;
+        height: 80%;
+    }
+
+    &.clickBtn,
+    &.clickBtnLabel {
+        cursor: pointer;
+        flex-direction: column;
+
+        svg {
+            width: 50% !important;
+            height: 50%;
+        }
+    }
+
+    &.clickBtnLabel {
+        svg {
+            margin-top: -4px;
+        }
+    }
+
+    &.textBtn {
+        display: grid;
+        /* grid-row: auto; */
+        grid-auto-flow: column;
+        cursor: pointer;
+        width: 100%;
+        justify-content: center;
+        align-items: center;
+        justify-items: center;
+    }
+
+    &.tglBtn,
+    &.tglBtnLabel {
+        cursor: pointer;
+        flex-direction: column;
+
+        &.switch {
+            //TOGGLE
+
+            .switch {
+                position: relative;
+                display: inline-block;
+                width: 100%;
+                height: 25px;
+                margin: 0;
+            }
+
+            .switch input {
+                opacity: 0;
+                width: 0;
+                height: 0;
+            }
+
+            .slider {
+                position: absolute;
+                cursor: pointer;
+                top: 0;
+                left: 0;
+                right: 0;
+                bottom: 0;
+                background-color: lightgrey;
+                -webkit-transition: 0.4s;
+                transition: 0.4s;
+            }
+
+            .slider:before {
+                position: absolute;
+                content: '';
+                height: 21px;
+                width: 21px;
+                left: 2px;
+                bottom: 2px;
+                background-color: $white;
+                -webkit-transition: 0.4s;
+                transition: 0.4s;
+            }
+
+            input:checked + .slider {
+                background-color: $medium-blue;
+            }
+
+            input:focus + .slider {
+                box-shadow: 0 0 1px $medium-blue;
+            }
+
+            input:checked + .slider:before {
+                -webkit-transform: translateX(26px);
+                -ms-transform: translateX(26px);
+                transform: translateX(26px);
+            }
+
+            /* Rounded sliders */
+            .slider.round {
+                border-radius: $standard-border-radius;
+            }
+
+            .slider.round:before {
+                border-radius: $standard-border-radius;
+            }
+        }
+
+        svg {
+            width: 50% !important;
+            height: 50%;
+        }
+
+        &:hover {
+            background-color: rgba(0, 0, 0, 0.3);
+        }
+    }
+
+    &.tglBtnLabel {
+        svg {
+            margin-top: -4px;
+        }
+    }
+
+    &.toolBtn,
+    &.toolBtnLabel {
+        cursor: pointer;
+        width: 100%;
+        border-radius: 100%;
+        flex-direction: column;
+        // margin-top: -4px;
+
+        svg {
+            width: 60% !important;
+            height: 60%;
+        }
+    }
+
+    &.toolBtnLabel {
+        svg {
+            margin-top: -4px;
+        }
+    }
+
+    &.menuBtn {
+        cursor: pointer !important;
+        border-radius: 0px;
+        flex-direction: column;
+
+        svg {
+            width: 45% !important;
+            height: 45%;
+        }
+
+        &:hover {
+            filter: brightness(0.85);
+        }
+    }
+
+    &.colorBtn,
+    &.colorBtnLabel {
+        color: black;
+        cursor: pointer;
+        flex-direction: column;
+        background: transparent;
+
+        .colorButton-color {
+            margin-top: 3px;
+            width: 80%;
+            height: 3px;
+        }
+
+        .menuButton-dropdownBox {
+            position: absolute;
+            width: fit-content;
+            height: fit-content;
+            color: black;
+            top: 100%;
+            left: 0;
+            z-index: 21;
+            background-color: #e3e3e3;
+            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+            border-radius: 3px;
+        }
+    }
+
+    &.colorBtnLabel {
+        svg {
+            margin-top: -4px;
+        }
+    }
+
+    &.drpdownList {
+        width: 100%;
+        display: grid;
+        grid-auto-columns: 80px 20px;
+        justify-items: center;
+        font-family: 'Roboto';
+        white-space: nowrap;
+        text-overflow: ellipsis;
+        font-size: 13;
+        font-weight: 600;
+        overflow: hidden;
+        cursor: pointer;
+        background: transparent;
+        align-content: center;
+        align-items: center;
+
+        .menuButton-dropdownList {
+            position: absolute;
+            width: 150px;
+            height: fit-content;
+            top: 100%;
+            z-index: 21;
+            background-color: $white;
+            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+            padding: 1px;
+
+            .list-item {
+                color: $black;
+                width: 100%;
+                height: 25px;
+                font-weight: 400;
+                display: flex;
+                justify-content: left;
+                align-items: center;
+                padding-left: 5px;
+            }
+
+            .list-item:hover {
+                background-color: lightgrey;
+            }
+        }
+    }
+
+    &.numBtn {
+        cursor: pointer;
+        background: transparent;
+
+        &.slider {
+            color: $white;
+            cursor: pointer;
+            flex-direction: column;
+            background: transparent;
+
+            .menu-slider {
+                width: 100px;
+            }
+
+            .menuButton-dropdownBox {
+                position: absolute;
+                width: fit-content;
+                height: fit-content;
+                top: 100%;
+                z-index: 21;
+                background-color: #e3e3e3;
+                box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+                border-radius: $standard-border-radius;
+
+                .menu-slider {
+                    height: 10px;
+                }
+                input[type='range']::-webkit-slider-runnable-track {
+                    background: gray;
+                    height: 3px;
+                }
+
+                input[type='range']::-webkit-slider-thumb {
+                    box-shadow: 1px 1px 1px #000000;
+                    border: 1px solid #000000;
+                    height: 10px;
+                    width: 10px;
+                    border-radius: 5px;
+                    background: #ffffff;
+                    cursor: pointer;
+                    -webkit-appearance: none;
+                    margin-top: -4px;
+                }
+            }
+        }
+
+        .button {
+            width: 25%;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+
+            &.number {
+                width: 50%;
+
+                .button-input {
+                    background: none;
+                    border: none;
+                    text-align: right;
+                    width: 100%;
+                    color: $white;
+                    height: 100%;
+                    text-align: center;
+                }
+
+                .button-input:focus {
+                    outline: none;
+                }
+            }
+        }
+
+        &.list {
+            width: 100%;
+            justify-content: space-around;
+            border: $standard-border;
+
+            .menuButton-dropdownList {
+                position: absolute;
+                width: fit-content;
+                height: fit-content;
+                min-width: 50%;
+                max-height: 50vh;
+                overflow-y: scroll;
+                top: 100%;
+                z-index: 21;
+                background-color: $white;
+                box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+                padding: 1px;
+
+                .list-item {
+                    color: $black;
+                    width: 100%;
+                    height: 25px;
+                    font-weight: 400;
+                    display: flex;
+                    justify-content: center;
+                    align-items: center;
+                }
+
+                .list-item:hover {
+                    background-color: lightgrey;
+                }
+            }
+        }
+    }
+
+    &.editableText {
+        cursor: text;
+        display: flex;
+        flex-direction: row;
+        gap: 5px;
+        padding-left: 10px;
+        justify-content: flex-start;
+        color: black;
+        background-color: $light-gray;
+        padding: 5px;
+        padding-left: 10px;
+        width: 100%;
+        height: 100%;
+    }
+
+    &.drpDownBtn {
+        cursor: pointer;
+        background: transparent;
+        border: solid 0.5px grey;
+
+        &.true {
+            background: rgba(0, 0, 0, 0.3);
+        }
+
+        .menuButton-dropdownBox {
+            position: absolute;
+            width: 150px;
+            height: 250px;
+            top: 100%;
+            background-color: #e3e3e3;
+            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
+            border-radius: $standard-border-radius;
+        }
+    }
+
+    .menuButton-dropdown {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        font-size: 15px;
+        grid-column: 2;
+        border-radius: 0px 7px 7px 0px;
+        width: 13px;
+        height: 100%;
+        right: 0;
+    }
+
+    .menuButton-dropdown-header {
+        width: 100%;
+        font-weight: 300;
+        padding: 5px;
+        overflow: hidden;
+        font-size: 12px;
+        white-space: nowrap;
+        text-overflow: ellipsis;
+    }
+
+    .dropbox-background {
+        width: 200vw;
+        height: 200vh;
+        top: -100vh;
+        z-index: 20;
+        left: -100vw;
+        background: transparent;
+        position: fixed;
+    }
+}
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
new file mode 100644
index 000000000..2958fa737
--- /dev/null
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -0,0 +1,412 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, NumberDropdown, NumberDropdownType, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc, DocListCast, StrListCast } from '../../../../fields/Doc';
+import { ScriptField } from '../../../../fields/ScriptField';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
+import { SelectionManager } from '../../../util/SelectionManager';
+import { undoable, UndoManager } from '../../../util/UndoManager';
+import { ContextMenu } from '../../ContextMenu';
+import { DocComponent } from '../../DocComponent';
+import { EditableView } from '../../EditableView';
+import { Colors } from '../../global/globalEnums';
+import { StyleProp } from '../../StyleProvider';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { OpenWhere } from '../DocumentView';
+import { RichTextMenu } from '../formattedText/RichTextMenu';
+import './FontIconBox.scss';
+import { SelectedDocView } from '../../selectedDoc';
+
+export enum ButtonType {
+    TextButton = 'textBtn',
+    MenuButton = 'menuBtn',
+    DropdownList = 'dropdownList',
+    DropdownButton = 'dropdownBtn',
+    ClickButton = 'clickBtn',
+    ToggleButton = 'toggleBtn',
+    ColorButton = 'colorBtn',
+    ToolButton = 'toolBtn',
+    MultiToggleButton = 'multiToggleBtn',
+    NumberSliderButton = 'numSliderBtn',
+    NumberDropdownButton = 'numDropdownBtn',
+    NumberInlineButton = 'numInlineBtn',
+    EditableText = 'editableText',
+}
+
+export interface ButtonProps extends FieldViewProps {
+    type?: ButtonType;
+}
+@observer
+export class FontIconBox extends DocComponent<ButtonProps>() {
+    public static LayoutString(fieldKey: string) {
+        return FieldView.LayoutString(FontIconBox, fieldKey);
+    }
+    @observable noTooltip = false;
+    showTemplate = (): void => {
+        const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
+        dragFactory && this.props.addDocTab(dragFactory, OpenWhere.addRight);
+    };
+    dragAsTemplate = (): void => {
+        this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
+    };
+    useAsPrototype = (): void => {
+        this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)');
+    };
+
+    specificContextMenu = (): void => {
+        if (!Doc.noviceMode) {
+            const cm = ContextMenu.Instance;
+            cm.addItem({ description: 'Show Template', event: this.showTemplate, icon: 'tag' });
+            cm.addItem({ description: 'Use as Render Template', event: this.dragAsTemplate, icon: 'tag' });
+            cm.addItem({ description: 'Use as Prototype', event: this.useAsPrototype, icon: 'tag' });
+        }
+    };
+
+    static GetShowLabels() {
+        return BoolCast(Doc.UserDoc()._showLabel);
+    }
+    static SetShowLabels(show: boolean) {
+        Doc.UserDoc()._showLabel = show;
+    }
+    static GetRecognizeGestures() {
+        return BoolCast(Doc.UserDoc()._recognizeGestures);
+    }
+    static SetRecognizeGestures(show: boolean) {
+        Doc.UserDoc()._recognizeGestures = show;
+    }
+
+    // Determining UI Specs
+    @computed get label() {
+        return StrCast(this.rootDoc.icon_label, StrCast(this.rootDoc.title));
+    }
+    Icon = (color: string, iconFalse?: boolean) => {
+        let icon;
+        if (iconFalse ) {
+            icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any;
+            if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />
+            else return null
+        }
+        icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any;
+        const trailsIcon = () => <img src={`/assets/${'presTrails.png'}`} style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? '0%' : '100%'})` }} />;
+        return !icon ? null : icon === 'pres-trail' ? trailsIcon() : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
+    };
+    @computed get dropdown() {
+        return BoolCast(this.rootDoc.dropDownOpen);
+    }
+    @computed get buttonList() {
+        return StrListCast(this.rootDoc.btnList);
+    }
+    @computed get type() {
+        return StrCast(this.rootDoc.btnType);
+    }
+
+    /**
+     * Types of buttons in dash:
+     * - Main menu button (LHS)
+     * - Tool button
+     * - Expandable button (CollectionLinearView)
+     * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
+     * - Action button
+     * - Dropdown button
+     * - Color button
+     * - Dropdown list
+     * - Number button
+     **/
+
+    _batch: UndoManager.Batch | undefined = undefined;
+    /**
+     * Number button
+     */
+    @computed get numberDropdown() {
+        let type: NumberDropdownType;
+        switch(this.type) {
+            case ButtonType.NumberDropdownButton: 
+                type = 'dropdown'
+                break;
+            case ButtonType.NumberInlineButton:
+                type = 'input'
+                break;
+            case ButtonType.NumberSliderButton:
+            default:
+                type = 'slider'
+                break;
+        }
+        const numScript = (value?: number) => ScriptCast(this.rootDoc.script).script.run({ self: this.rootDoc, value, _readOnly_: value === undefined });
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        // Script for checking the outcome of the toggle
+        const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)));
+        const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>;
+
+        return <NumberDropdown 
+            color={color} 
+            numberDropdownType={type} 
+            showPlusMinus={false} 
+            tooltip={this.label}
+            type={Type.PRIM}
+            min={NumCast(this.rootDoc.numBtnMin, 0)}
+            max={NumCast(this.rootDoc.numBtnMax, 100)}
+            number={checkResult} 
+            setNumber={undoable(value => numScript(value), `${this.rootDoc.title} button set from list`)}
+            fillWidth
+        />
+    }
+
+    /**
+     * Dropdown button
+     */
+    @computed get dropdownButton() {
+        const active: string = StrCast(this.rootDoc.dropDownOpen);
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        return (
+            <div
+                className={`menuButton ${this.type} ${active}`}
+                style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
+                onClick={action(() => {
+                    this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen;
+                    this.noTooltip = this.rootDoc.dropDownOpen;
+                    Doc.UnBrushAllDocs();
+                })}>
+                {this.Icon(color)}
+                {!this.label || !FontIconBox.GetShowLabels() ? null : (
+                    <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
+                        {' '}
+                        {this.label}{' '}
+                    </div>
+                )}
+                <div className="menuButton-dropdown" style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
+                    <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
+                </div>
+                {this.rootDoc.dropDownOpen ? <div className="menuButton-dropdownBox">{/* DROPDOWN BOX CONTENTS */}</div> : null}
+            </div>
+        );
+    }
+
+    /**
+     * Dropdown list
+     */
+    @computed get dropdownListButton() {
+        const active: string = StrCast(this.rootDoc.dropDownOpen);
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+        const script = ScriptCast(this.rootDoc.script);
+
+        let noviceList: string[] = [];
+        let text: string | undefined;
+        let dropdown = true;
+        let getStyle: (val: string) => any = () => {};
+        let icon: IconProp = 'caret-down';
+        let isViewDropdown: boolean = script?.script.originalScript.startsWith('setView')
+        try {
+            if (isViewDropdown) {
+                const selectedDocs: Doc[] = SelectionManager.Docs();
+                const selected = SelectionManager.Docs().lastElement();
+                console.log('selected')
+                if (selected) {
+                    if (StrCast(selected.type) === DocumentType.COL) {
+                        text = StrCast(selected._type_collection);
+                    } else {
+                        console.log("doc selected", selected.title);
+                        dropdown = false;
+                        if (selectedDocs.length > 1) {
+                            text = selectedDocs.length + " documents selected"
+                        } else {
+                            text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type);
+                            icon = Doc.toIcon(selected);
+                        }
+                        return <Popup
+                            icon={<FontAwesomeIcon size={'1x'} icon={icon} />}
+                            text={text}
+                            type={Type.TERT}
+                            color={color}
+                            popup={<SelectedDocView selectedDocs={selectedDocs}/>}
+                            fillWidth
+                        />
+                    }
+                } else {
+                    dropdown = false;
+                    return <Button 
+                        text={`None Selected`} 
+                        type={Type.TERT}
+                        color={color}
+                        fillWidth
+                        inactive
+                    />
+                }
+                noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
+            } else { 
+                text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
+                getStyle = (val: string) => { return { fontFamily: val } }
+            }
+        } catch (e) {
+            console.log(e);
+        }
+
+        console.log("current item: ", text);
+
+        // Get items to place into the list
+        const list: IListItemProps[] = this.buttonList
+            .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value))
+            .map(value => (
+                {
+                    text: value.charAt(0).toUpperCase() + value.slice(1),
+                    val: value,
+                    style: getStyle(value),
+                    onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value)
+                    // shortcut: '#',
+                }
+            ));
+
+
+        return (
+            <Dropdown 
+                selectedVal={text}
+                setSelectedVal={undoable((val) => script.script.run({ self: this.rootDoc, val }), `dropdown select ${this.label}`)}
+                color={color} 
+                type={isViewDropdown ? Type.TERT : Type.PRIM} 
+                dropdownType={DropdownType.SELECT} 
+                items={list}
+                tooltip={this.label}
+                fillWidth
+            />
+        )
+    }
+
+
+    @computed get colorScript() {
+        return ScriptCast(this.rootDoc.script);
+    }
+
+    /**
+     * Color button
+     */
+    @computed get colorButton() {
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent';
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
+
+        return (
+            <ColorPicker 
+                setSelectedColor={(value) => {
+                    const s = this.colorScript;
+                    s && undoable(() => s.script.run({ self: this.rootDoc, value: value, _readOnly_: false }).result, `Set ${tooltip} to ${value}`)();
+                }}
+                selectedColor={curColor}
+                type={Type.PRIM}
+                color={color}
+                icon={this.Icon(color)!}
+                tooltip={tooltip}
+                label={this.label}
+            />
+        )
+    }
+
+    @computed get toggleButton() {
+        // Determine the type of toggle button
+        const buttonText: string = StrCast(this.rootDoc.buttonText);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
+
+        const script = ScriptCast(this.rootDoc.onClick);
+        const toggleStatus = script ? script.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result : false;
+        // Colors
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+
+        console.log(tooltip, toggleStatus);
+        return (
+            <Toggle tooltip={`Toggle ${tooltip}`} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={toggleStatus} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
+        )
+    }
+
+    /**
+     * Default
+     */
+    @computed get defaultButton() {
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
+
+        return (
+            <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label}/>
+        )
+    }
+
+    @computed get editableText() {
+        // Script for running the toggle
+        const script = ScriptCast(this.rootDoc.script);
+        // Function to run the script
+        const checkResult = script?.script.run({ value: '', _readOnly_: true }).result;
+
+        const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
+        
+        return <EditableText 
+            editing={false} setEditing={(editing: boolean) => {}}            
+        />
+        
+        return (
+            <div className="menuButton editableText">
+                <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} />
+                <div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
+                    <EditableView GetValue={() => script?.script.run({ value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
+                </div>
+            </div>
+        );
+    }
+
+    render() {
+        // determine dash button metadata
+        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
+        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
+        const tooltip: string = StrCast(this.rootDoc.toolTip);
+
+        // TODO:glr Add label of button type
+        let button: JSX.Element = this.defaultButton;
+        // prettier-ignore
+        switch (this.type) {
+            case ButtonType.EditableText: 
+                button = this.editableText;
+                break;
+            case ButtonType.DropdownList:
+                button = this.dropdownListButton;
+                break;
+            case ButtonType.ColorButton: 
+                button = this.colorButton; 
+                break;
+            case ButtonType.NumberDropdownButton: 
+            case ButtonType.NumberInlineButton:
+            case ButtonType.NumberSliderButton: 
+                button = this.numberDropdown; 
+                break;
+            case ButtonType.DropdownButton: 
+                button = this.dropdownButton; 
+                break;
+            case ButtonType.ToggleButton: button = this.toggleButton; break;
+            case ButtonType.TextButton: 
+                // Script for checking the outcome of the toggle
+                const script = ScriptCast(this.rootDoc.script);
+                const checkResult = script?.script.run({ _readOnly_: true }).result;
+                button = (
+                    <Button tooltip={tooltip} color={checkResult ?? backgroundColor} icon={this.Icon(color)!} text={StrCast(this.rootDoc.buttonText)} label={this.label}/>
+                );
+                break;
+            case ButtonType.ClickButton:
+            case ButtonType.ToolButton: 
+                button = (
+                    <IconButton tooltip={tooltip} color={color} icon={this.Icon(color)!} label={this.label}/>
+                );
+                break;
+            case ButtonType.MenuButton: button = (
+                    <IconButton tooltip={tooltip} tooltipPlacement='right' size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/>
+                );
+                break;
+        }
+
+        return button;
+    }
+}
diff --git a/src/client/views/nodes/button/FontIconBox.scss b/src/client/views/nodes/button/FontIconBox.scss
deleted file mode 100644
index 9d9fa26b0..000000000
--- a/src/client/views/nodes/button/FontIconBox.scss
+++ /dev/null
@@ -1,438 +0,0 @@
-@import '../../global/globalCssVariables';
-
-.menuButton {
-    height: 100%;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 80%;
-    border-radius: $standard-border-radius;
-    transition: 0.15s;
-
-    .menuButton-wrap {
-        grid-column: 1;
-        justify-content: center;
-        align-items: center;
-        text-align: center;
-    }
-
-    .fontIconBox-label {
-        color: $white;
-        bottom: -1;
-        position: absolute;
-        text-align: center;
-        font-size: 7px;
-        letter-spacing: normal;
-        background-color: inherit;
-        border-radius: 8px;
-        padding: 0;
-        width: 100%;
-        font-family: 'system-ui';
-        text-transform: uppercase;
-        font-weight: bold;
-        transition: 0.15s;
-    }
-
-    .fontIconBox-icon {
-        width: 80%;
-        height: 80%;
-    }
-
-    &.clickBtn,
-    &.clickBtnLabel {
-        cursor: pointer;
-        flex-direction: column;
-
-        svg {
-            width: 50% !important;
-            height: 50%;
-        }
-    }
-
-    &.clickBtnLabel {
-        svg {
-            margin-top: -4px;
-        }
-    }
-
-    &.textBtn {
-        display: grid;
-        /* grid-row: auto; */
-        grid-auto-flow: column;
-        cursor: pointer;
-        width: 100%;
-        justify-content: center;
-        align-items: center;
-        justify-items: center;
-    }
-
-    &.tglBtn,
-    &.tglBtnLabel {
-        cursor: pointer;
-        flex-direction: column;
-
-        &.switch {
-            //TOGGLE
-
-            .switch {
-                position: relative;
-                display: inline-block;
-                width: 100%;
-                height: 25px;
-                margin: 0;
-            }
-
-            .switch input {
-                opacity: 0;
-                width: 0;
-                height: 0;
-            }
-
-            .slider {
-                position: absolute;
-                cursor: pointer;
-                top: 0;
-                left: 0;
-                right: 0;
-                bottom: 0;
-                background-color: lightgrey;
-                -webkit-transition: 0.4s;
-                transition: 0.4s;
-            }
-
-            .slider:before {
-                position: absolute;
-                content: '';
-                height: 21px;
-                width: 21px;
-                left: 2px;
-                bottom: 2px;
-                background-color: $white;
-                -webkit-transition: 0.4s;
-                transition: 0.4s;
-            }
-
-            input:checked + .slider {
-                background-color: $medium-blue;
-            }
-
-            input:focus + .slider {
-                box-shadow: 0 0 1px $medium-blue;
-            }
-
-            input:checked + .slider:before {
-                -webkit-transform: translateX(26px);
-                -ms-transform: translateX(26px);
-                transform: translateX(26px);
-            }
-
-            /* Rounded sliders */
-            .slider.round {
-                border-radius: $standard-border-radius;
-            }
-
-            .slider.round:before {
-                border-radius: $standard-border-radius;
-            }
-        }
-
-        svg {
-            width: 50% !important;
-            height: 50%;
-        }
-
-        &:hover {
-            background-color: rgba(0, 0, 0, 0.3);
-        }
-    }
-
-    &.tglBtnLabel {
-        svg {
-            margin-top: -4px;
-        }
-    }
-
-    &.toolBtn,
-    &.toolBtnLabel {
-        cursor: pointer;
-        width: 100%;
-        border-radius: 100%;
-        flex-direction: column;
-        // margin-top: -4px;
-
-        svg {
-            width: 60% !important;
-            height: 60%;
-        }
-    }
-
-    &.toolBtnLabel {
-        svg {
-            margin-top: -4px;
-        }
-    }
-
-    &.menuBtn {
-        cursor: pointer !important;
-        border-radius: 0px;
-        flex-direction: column;
-
-        svg {
-            width: 45% !important;
-            height: 45%;
-        }
-
-        &:hover {
-            filter: brightness(0.85);
-        }
-    }
-
-    &.colorBtn,
-    &.colorBtnLabel {
-        color: black;
-        cursor: pointer;
-        flex-direction: column;
-        background: transparent;
-
-        .colorButton-color {
-            margin-top: 3px;
-            width: 80%;
-            height: 3px;
-        }
-
-        .menuButton-dropdownBox {
-            position: absolute;
-            width: fit-content;
-            height: fit-content;
-            color: black;
-            top: 100%;
-            left: 0;
-            z-index: 21;
-            background-color: #e3e3e3;
-            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
-            border-radius: 3px;
-        }
-    }
-
-    &.colorBtnLabel {
-        svg {
-            margin-top: -4px;
-        }
-    }
-
-    &.drpdownList {
-        width: 100%;
-        display: grid;
-        grid-auto-columns: 80px 20px;
-        justify-items: center;
-        font-family: 'Roboto';
-        white-space: nowrap;
-        text-overflow: ellipsis;
-        font-size: 13;
-        font-weight: 600;
-        overflow: hidden;
-        cursor: pointer;
-        background: transparent;
-        align-content: center;
-        align-items: center;
-
-        .menuButton-dropdownList {
-            position: absolute;
-            width: 150px;
-            height: fit-content;
-            top: 100%;
-            z-index: 21;
-            background-color: $white;
-            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
-            padding: 1px;
-
-            .list-item {
-                color: $black;
-                width: 100%;
-                height: 25px;
-                font-weight: 400;
-                display: flex;
-                justify-content: left;
-                align-items: center;
-                padding-left: 5px;
-            }
-
-            .list-item:hover {
-                background-color: lightgrey;
-            }
-        }
-    }
-
-    &.numBtn {
-        cursor: pointer;
-        background: transparent;
-
-        &.slider {
-            color: $white;
-            cursor: pointer;
-            flex-direction: column;
-            background: transparent;
-
-            .menu-slider {
-                width: 100px;
-            }
-
-            .menuButton-dropdownBox {
-                position: absolute;
-                width: fit-content;
-                height: fit-content;
-                top: 100%;
-                z-index: 21;
-                background-color: #e3e3e3;
-                box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
-                border-radius: $standard-border-radius;
-
-                .menu-slider {
-                    height: 10px;
-                }
-                input[type='range']::-webkit-slider-runnable-track {
-                    background: gray;
-                    height: 3px;
-                }
-
-                input[type='range']::-webkit-slider-thumb {
-                    box-shadow: 1px 1px 1px #000000;
-                    border: 1px solid #000000;
-                    height: 10px;
-                    width: 10px;
-                    border-radius: 5px;
-                    background: #ffffff;
-                    cursor: pointer;
-                    -webkit-appearance: none;
-                    margin-top: -4px;
-                }
-            }
-        }
-
-        .button {
-            width: 25%;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-
-            &.number {
-                width: 50%;
-
-                .button-input {
-                    background: none;
-                    border: none;
-                    text-align: right;
-                    width: 100%;
-                    color: $white;
-                    height: 100%;
-                    text-align: center;
-                }
-
-                .button-input:focus {
-                    outline: none;
-                }
-            }
-        }
-
-        &.list {
-            width: 100%;
-            justify-content: space-around;
-            border: $standard-border;
-
-            .menuButton-dropdownList {
-                position: absolute;
-                width: fit-content;
-                height: fit-content;
-                min-width: 50%;
-                max-height: 50vh;
-                overflow-y: scroll;
-                top: 100%;
-                z-index: 21;
-                background-color: $white;
-                box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
-                padding: 1px;
-
-                .list-item {
-                    color: $black;
-                    width: 100%;
-                    height: 25px;
-                    font-weight: 400;
-                    display: flex;
-                    justify-content: center;
-                    align-items: center;
-                }
-
-                .list-item:hover {
-                    background-color: lightgrey;
-                }
-            }
-        }
-    }
-
-    &.editableText {
-        cursor: text;
-        display: flex;
-        flex-direction: row;
-        gap: 5px;
-        padding-left: 10px;
-        justify-content: flex-start;
-        color: black;
-        background-color: $light-gray;
-        padding: 5px;
-        padding-left: 10px;
-        width: 100%;
-        height: 100%;
-    }
-
-    &.drpDownBtn {
-        cursor: pointer;
-        background: transparent;
-        border: solid 0.5px grey;
-
-        &.true {
-            background: rgba(0, 0, 0, 0.3);
-        }
-
-        .menuButton-dropdownBox {
-            position: absolute;
-            width: 150px;
-            height: 250px;
-            top: 100%;
-            background-color: #e3e3e3;
-            box-shadow: 0px 3px 4px rgba(0, 0, 0, 0.3);
-            border-radius: $standard-border-radius;
-        }
-    }
-
-    .menuButton-dropdown {
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        font-size: 15px;
-        grid-column: 2;
-        border-radius: 0px 7px 7px 0px;
-        width: 13px;
-        height: 100%;
-        right: 0;
-    }
-
-    .menuButton-dropdown-header {
-        width: 100%;
-        font-weight: 300;
-        padding: 5px;
-        overflow: hidden;
-        font-size: 12px;
-        white-space: nowrap;
-        text-overflow: ellipsis;
-    }
-
-    .dropbox-background {
-        width: 200vw;
-        height: 200vh;
-        top: -100vh;
-        z-index: 20;
-        left: -100vw;
-        background: transparent;
-        position: fixed;
-    }
-}
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
deleted file mode 100644
index e31407f4b..000000000
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ /dev/null
@@ -1,385 +0,0 @@
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, ColorPicker, Dropdown, DropdownType, EditableText, IconButton, IListItemProps, NumberDropdown, NumberDropdownType, Size, Toggle, ToggleType, Type } from 'browndash-components';
-import { action, computed, observable } from 'mobx';
-import { observer } from 'mobx-react';
-import * as React from 'react';
-import { Doc, StrListCast } from '../../../../fields/Doc';
-import { ScriptField } from '../../../../fields/ScriptField';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { CollectionViewType, DocumentType } from '../../../documents/DocumentTypes';
-import { SelectionManager } from '../../../util/SelectionManager';
-import { undoable, UndoManager } from '../../../util/UndoManager';
-import { ContextMenu } from '../../ContextMenu';
-import { DocComponent } from '../../DocComponent';
-import { EditableView } from '../../EditableView';
-import { Colors } from '../../global/globalEnums';
-import { StyleProp } from '../../StyleProvider';
-import { FieldView, FieldViewProps } from '.././FieldView';
-import { OpenWhere } from '../DocumentView';
-import { RichTextMenu } from '../formattedText/RichTextMenu';
-import './FontIconBox.scss';
-
-export enum ButtonType {
-    TextButton = 'textBtn',
-    MenuButton = 'menuBtn',
-    DropdownList = 'drpdownList',
-    DropdownButton = 'drpdownBtn',
-    ClickButton = 'clickBtn',
-    DoubleButton = 'dblBtn',
-    ToggleButton = 'tglBtn',
-    ColorButton = 'colorBtn',
-    ToolButton = 'toolBtn',
-    NumberSliderButton = 'numSliderBtn',
-    NumberDropdownButton = 'numDropdownBtn',
-    NumberInlineButton = 'numInlineBtn',
-    EditableText = 'editableText',
-}
-
-export interface ButtonProps extends FieldViewProps {
-    type?: ButtonType;
-}
-@observer
-export class FontIconBox extends DocComponent<ButtonProps>() {
-    public static LayoutString(fieldKey: string) {
-        return FieldView.LayoutString(FontIconBox, fieldKey);
-    }
-    @observable noTooltip = false;
-    showTemplate = (): void => {
-        const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
-        dragFactory && this.props.addDocTab(dragFactory, OpenWhere.addRight);
-    };
-    dragAsTemplate = (): void => {
-        this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)');
-    };
-    useAsPrototype = (): void => {
-        this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)');
-    };
-
-    specificContextMenu = (): void => {
-        if (!Doc.noviceMode) {
-            const cm = ContextMenu.Instance;
-            cm.addItem({ description: 'Show Template', event: this.showTemplate, icon: 'tag' });
-            cm.addItem({ description: 'Use as Render Template', event: this.dragAsTemplate, icon: 'tag' });
-            cm.addItem({ description: 'Use as Prototype', event: this.useAsPrototype, icon: 'tag' });
-        }
-    };
-
-    static GetShowLabels() {
-        return BoolCast(Doc.UserDoc()._showLabel);
-    }
-    static SetShowLabels(show: boolean) {
-        Doc.UserDoc()._showLabel = show;
-    }
-    static GetRecognizeGestures() {
-        return BoolCast(Doc.UserDoc()._recognizeGestures);
-    }
-    static SetRecognizeGestures(show: boolean) {
-        Doc.UserDoc()._recognizeGestures = show;
-    }
-
-    // Determining UI Specs
-    @computed get label() {
-        return StrCast(this.rootDoc.icon_label, StrCast(this.rootDoc.title));
-    }
-    Icon = (color: string, iconFalse?: boolean) => {
-        let icon;
-        if (iconFalse ) {
-            icon = StrCast(this.dataDoc[this.fieldKey ?? 'iconFalse'] ?? this.dataDoc.icon, 'user') as any;
-            if (icon) return <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />
-            else return null
-        }
-        icon = StrCast(this.dataDoc[this.fieldKey ?? 'icon'] ?? this.dataDoc.icon, 'user') as any;
-        const trailsIcon = () => <img src={`/assets/${'presTrails.png'}`} style={{ width: 30, height: 30, filter: `invert(${color === Colors.DARK_GRAY ? '0%' : '100%'})` }} />;
-        return !icon ? null : icon === 'pres-trail' ? trailsIcon() : <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={icon} color={color} />;
-    };
-    @computed get dropdown() {
-        return BoolCast(this.rootDoc.dropDownOpen);
-    }
-    @computed get buttonList() {
-        return StrListCast(this.rootDoc.btnList);
-    }
-    @computed get type() {
-        return StrCast(this.rootDoc.btnType);
-    }
-
-    /**
-     * Types of buttons in dash:
-     * - Main menu button (LHS)
-     * - Tool button
-     * - Expandable button (CollectionLinearView)
-     * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
-     * - Action button
-     * - Dropdown button
-     * - Color button
-     * - Dropdown list
-     * - Number button
-     **/
-
-    _batch: UndoManager.Batch | undefined = undefined;
-    /**
-     * Number button
-     */
-    @computed get numberDropdown() {
-        let type: NumberDropdownType;
-        switch(this.type) {
-            case ButtonType.NumberDropdownButton: 
-                type = 'dropdown'
-                break;
-            case ButtonType.NumberInlineButton:
-                type = 'input'
-                break;
-            case ButtonType.NumberSliderButton:
-            default:
-                type = 'slider'
-                break;
-        }
-        const numScript = (value?: number) => ScriptCast(this.rootDoc.script).script.run({ self: this.rootDoc, value, _readOnly_: value === undefined });
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        // Script for checking the outcome of the toggle
-        const checkResult = Number(Number(numScript().result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3)));
-        const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>;
-
-        return <NumberDropdown 
-            color={color} 
-            numberDropdownType={type} 
-            showPlusMinus={false} 
-            min={NumCast(this.rootDoc.numBtnMin, 0)}
-            max={NumCast(this.rootDoc.numBtnMax, 100)}
-            number={checkResult} 
-            setNumber={undoable(value => numScript(value), `${this.rootDoc.title} button set from list`)}
-        />
-    }
-
-    /**
-     * Dropdown button
-     */
-    @computed get dropdownButton() {
-        const active: string = StrCast(this.rootDoc.dropDownOpen);
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        return (
-            <div
-                className={`menuButton ${this.type} ${active}`}
-                style={{ color: color, backgroundColor: backgroundColor, borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
-                onClick={action(() => {
-                    this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen;
-                    this.noTooltip = this.rootDoc.dropDownOpen;
-                    Doc.UnBrushAllDocs();
-                })}>
-                {this.Icon(color)}
-                {!this.label || !FontIconBox.GetShowLabels() ? null : (
-                    <div className="fontIconBox-label" style={{ color: color, backgroundColor: backgroundColor }}>
-                        {' '}
-                        {this.label}{' '}
-                    </div>
-                )}
-                <div className="menuButton-dropdown" style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
-                    <FontAwesomeIcon icon={'caret-down'} color={color} size="sm" />
-                </div>
-                {this.rootDoc.dropDownOpen ? <div className="menuButton-dropdownBox">{/* DROPDOWN BOX CONTENTS */}</div> : null}
-            </div>
-        );
-    }
-
-    /**
-     * Dropdown list
-     */
-    @computed get dropdownListButton() {
-        const active: string = StrCast(this.rootDoc.dropDownOpen);
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-
-        const script = ScriptCast(this.rootDoc.script);
-
-        let noviceList: string[] = [];
-        let text: string | undefined;
-        let dropdown = true;
-        let icon: IconProp = 'caret-down';
-        try {
-            if (script?.script.originalScript.startsWith('setView')) {
-                const selected = SelectionManager.Docs().lastElement();
-                console.log('selected')
-                if (selected) {
-                    if (StrCast(selected.type) === DocumentType.COL) {
-                        text = StrCast(selected._type_collection);
-                    } else {
-                        console.log("doc selected", selected.title)
-                        dropdown = false;
-                        text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type);
-                        icon = Doc.toIcon(selected);
-                        return <div>Hi!</div>
-                    }
-                } else {
-                    dropdown = false;
-                    icon = 'globe-asia';
-                    text = 'User Default';
-                    return <div>Hi!</div>
-                }
-                noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
-            } else text = StrCast((RichTextMenu.Instance?.TextView?.EditorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
-        } catch (e) {
-            console.log(e);
-        }
-
-        console.log("current item: ", text);
-
-        // Get items to place into the list
-        const list: IListItemProps[] = this.buttonList
-            .filter(value => !Doc.noviceMode || !noviceList.length || noviceList.includes(value))
-            .map(value => (
-                {
-                    text: value,
-                    val: value,
-                    style: { fontFamily: value },
-                    onClick: undoable(() => script.script.run({ self: this.rootDoc, value }), value)
-                    // shortcut: '#',
-                }
-            ));
-
-
-        return (
-            <Dropdown 
-                selectedVal={text}
-                setSelectedVal={undoable((val) => script.script.run({ self: this.rootDoc, val }), `dropdown select ${this.label}`)}
-                color={Colors.WHITE} 
-                type={Type.PRIM} 
-                dropdownType={DropdownType.SELECT} 
-                items={list}
-                tooltip={this.label}
-            />
-        )
-    }
-
-
-    @computed get colorScript() {
-        return ScriptCast(this.rootDoc.script);
-    }
-
-    /**
-     * Color button
-     */
-    @computed get colorButton() {
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const curColor = this.colorScript?.script.run({ self: this.rootDoc, value: undefined, _readOnly_: true }).result ?? 'transparent';
-        const tooltip: string = StrCast(this.rootDoc.toolTip);
-
-        return (
-            <ColorPicker 
-                setSelectedColor={(value) => {
-                    const s = this.colorScript;
-                    s && undoable(() => s.script.run({ self: this.rootDoc, value: value, _readOnly_: false }).result, `Set ${tooltip} to ${value}`)();
-                }}
-                selectedColor={curColor}
-                type={Type.PRIM}
-                color={color}
-                icon={this.Icon(color)!}
-                tooltip={tooltip}
-                label={this.label}
-            />
-        )
-    }
-
-    @computed get toggleButton() {
-        // Determine the type of toggle button
-        const switchToggle: boolean = BoolCast(this.rootDoc.switchToggle);
-        const buttonText: string = StrCast(this.rootDoc.buttonText);
-        const tooltip: string = StrCast(this.rootDoc.toolTip);
-        
-        // Colors
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-
-        console.log(buttonText, tooltip);
-        return (
-            <Toggle tooltip={`Toggle + ${tooltip}`} toggleType={ToggleType.BUTTON} type={Type.PRIM} toggleStatus={switchToggle} text={buttonText} color={color} icon={this.Icon(color)!} label={this.label}/>
-        )
-    }
-
-    /**
-     * Default
-     */
-    @computed get defaultButton() {
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const tooltip: string = StrCast(this.rootDoc.toolTip);
-
-        return (
-            <IconButton tooltip={tooltip} icon={this.Icon(color)!} label={this.label}/>
-        )
-    }
-
-    @computed get editableText() {
-        // Script for running the toggle
-        const script = ScriptCast(this.rootDoc.script);
-        // Function to run the script
-        const checkResult = script?.script.run({ value: '', _readOnly_: true }).result;
-
-        const setValue = (value: string, shiftDown?: boolean): boolean => script?.script.run({ value, _readOnly_: false }).result;
-        
-        return <EditableText 
-            editing={false} onEdit={() => {}} setEditing={(editing: boolean) => {}}            
-        />
-        
-        return (
-            <div className="menuButton editableText">
-                <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} />
-                <div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
-                    <EditableView GetValue={() => script?.script.run({ value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
-                </div>
-            </div>
-        );
-    }
-
-    render() {
-        // determine dash button metadata
-        const color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
-        const backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
-        const tooltip: string = StrCast(this.rootDoc.toolTip);
-
-        // TODO:glr Add label of button type
-        let button: JSX.Element = this.defaultButton;
-        // prettier-ignore
-        switch (this.type) {
-            case ButtonType.EditableText: 
-                button = this.editableText;
-                break;
-            case ButtonType.DropdownList:
-                button = this.dropdownListButton;
-                break;
-            case ButtonType.ColorButton: 
-                button = this.colorButton; 
-                break;
-            case ButtonType.NumberDropdownButton: 
-            case ButtonType.NumberInlineButton:
-            case ButtonType.NumberSliderButton: 
-                button = this.numberDropdown; 
-                break;
-            case ButtonType.DropdownButton: 
-                button = this.dropdownButton; 
-                break;
-            case ButtonType.ToggleButton: button = this.toggleButton; break;
-            case ButtonType.TextButton: 
-                // Script for checking the outcome of the toggle
-                const script = ScriptCast(this.rootDoc.script);
-                const checkResult = script?.script.run({ _readOnly_: true }).result;
-                button = (
-                    <Button tooltip={tooltip} color={checkResult ?? backgroundColor} icon={this.Icon(color)!} text={StrCast(this.rootDoc.buttonText)} label={this.label}/>
-                );
-                break;
-            case ButtonType.ClickButton:
-            case ButtonType.ToolButton: 
-                button = (
-                    <IconButton tooltip={tooltip} color={color} icon={this.Icon(color)!} label={this.label}/>
-                );
-                break;
-            case ButtonType.MenuButton: button = (
-                    <IconButton tooltip={tooltip} tooltipPlacement='right' size={Size.LARGE} color={color} icon={this.Icon(color)!} label={this.label}/>
-                );
-                break;
-        }
-
-        return button;
-    }
-}
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 5480600b0..64ea4f52c 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -15,6 +15,8 @@ import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
 import { LightboxView } from '../LightboxView';
 import { EditorView } from 'prosemirror-view';
 import './AnchorMenu.scss';
+import { ColorPicker, Group, IconButton, Popup, Size, Type } from 'browndash-components';
+import { StrCast } from '../../../fields/Types';
 
 @observer
 export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
@@ -42,7 +44,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     ];
 
     @observable private highlightColor: string = 'rgba(245, 230, 95, 0.616)';
-    @observable private _showLinkPopup: boolean = false;
 
     @observable public Status: 'marquee' | 'annotation' | '' = '';
 
@@ -131,7 +132,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             () => this._opacity,
             opacity => {
                 if (!opacity) {
-                    this._showLinkPopup = false;
                     this.setGPTPopupVis(false);
                     this.setGPTPopupText('');
                 }
@@ -141,7 +141,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         this._disposer = reaction(
             () => SelectionManager.Views().slice(),
             selected => {
-                this._showLinkPopup = false;
                 this.setGPTPopupVis(false);
                 this.setGPTPopupText('');
                 AnchorMenu.Instance.fadeOut(true);
@@ -253,49 +252,25 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         AnchorMenu.Instance.fadeOut(true);
     };
 
-    @action
-    toggleLinkPopup = (e: React.MouseEvent) => {
-        //ignore the potential null type error because this method cannot be called unless the user selects text and clicks the link button
-        //change popup visibility field to visible
-        this._showLinkPopup = !this._showLinkPopup;
-    };
-
     @computed get highlighter() {
-        const button = (
-            <button className="antimodeMenu-button anchor-color-preview-button" title="" key="highlighter-button" onClick={this.highlightClicked}>
-                <div className="anchor-color-preview">
-                    <FontAwesomeIcon icon="highlighter" size="lg" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />
-                    <div className="color-preview" style={{ backgroundColor: this.highlightColor }}></div>
-                </div>
-            </button>
-        );
-
-        const dropdownContent = (
-            <div className="dropdown">
-                <p>Change highlighter color:</p>
-                <div className="color-wrapper">
-                    {this._palette.map(color => {
-                        if (color) {
-                            return this.highlightColor === color ? (
-                                <button className="color-button active" key={`active ${color}`} style={{ backgroundColor: color }} onPointerDown={e => this.changeHighlightColor(color, e)}></button>
-                            ) : (
-                                <button className="color-button" key={`inactive ${color}`} style={{ backgroundColor: color }} onPointerDown={e => this.changeHighlightColor(color, e)}></button>
-                            );
-                        }
-                    })}
-                </div>
-            </div>
-        );
-        return (
-            <Tooltip key="highlighter" title={<div className="dash-tooltip">{'Click to Highlight'}</div>}>
-                <div className="anchorMenu-highlighter">
-                    <ButtonDropdown key={'highlighter'} button={button} dropdownContent={dropdownContent} pdf={true} />
-                </div>
-            </Tooltip>
-        );
+        return <Group>
+            <IconButton 
+                icon={<FontAwesomeIcon icon="highlighter" style={{ transition: 'transform 0.1s', transform: 'rotate(-45deg)' }} />}
+                tooltip={'Click to Highlight'}
+                onClick={this.highlightClicked}
+                colorPicker={this.highlightColor}
+                color={StrCast(Doc.UserDoc().userColor)}
+            />
+            <ColorPicker
+                colorPickerType={'github'}
+                selectedColor={this.highlightColor}
+                setSelectedColor={color => this.changeHighlightColor(color)}
+                size={Size.XSMALL}
+            />
+        </Group>
     }
 
-    @action changeHighlightColor = (color: string, e: React.PointerEvent) => {
+    @action changeHighlightColor = (color: string) => {
         const col: ColorState = {
             hex: color,
             hsl: { a: 0, h: 0, s: 0, l: 0, source: '' },
@@ -304,8 +279,6 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             oldHue: 0,
             source: '',
         };
-        e.preventDefault();
-        e.stopPropagation();
         this.highlightColor = Utils.colorString(col);
     };
 
@@ -339,11 +312,12 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             this.Status === 'marquee' ? (
                 <>
                     {this.highlighter}
-                    <Tooltip key="annotate" title={<div className="dash-tooltip">Drag to Place Annotation</div>}>
-                        <button className="antimodeMenu-button annotate" ref={this._commentCont} onPointerDown={this.pointerDown} style={{ cursor: 'grab' }}>
-                            <FontAwesomeIcon icon="comment-alt" size="lg" />
-                        </button>
-                    </Tooltip>
+                    <IconButton 
+                        tooltip={'Drag to Place Annotation'} 
+                        onPointerDown={this.pointerDown} 
+                        icon={<FontAwesomeIcon icon="comment-alt"/>}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />
                     {/* GPT Summarize icon only shows up when text is highlighted, not on marquee selection*/}
                     {AnchorMenu.Instance.StartCropDrag === unimplementedFunction && this.canSummarize() && (
                         <Tooltip key="gpt" title={<div className="dash-tooltip">Summarize with AI</div>}>
@@ -364,32 +338,35 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                         mode={this.GPTMode}
                     />
                     {AnchorMenu.Instance.OnAudio === unimplementedFunction ? null : (
-                        <Tooltip key="annoaudiotate" title={<div className="dash-tooltip">Click to Record Annotation</div>}>
-                            <button className="antimodeMenu-button annotate" onPointerDown={this.audioDown} style={{ cursor: 'grab' }}>
-                                <FontAwesomeIcon icon="microphone" size="lg" />
-                            </button>
-                        </Tooltip>
+                        <IconButton 
+                            tooltip={'Click to Record Annotation'}
+                            onPointerDown={this.audioDown}
+                            icon={<FontAwesomeIcon icon="microphone" />}
+                            color={StrCast(Doc.UserDoc().userColor)}
+                        />
                     )}
                     {this.canEdit() && (
-                        <Tooltip key="gpttextedit" title={<div className="dash-tooltip">AI edit suggestions</div>}>
-                            <button className="antimodeMenu-button annotate" onPointerDown={this.gptEdit} style={{ cursor: 'grab' }}>
-                                <FontAwesomeIcon icon="pencil-alt" size="lg" />
-                            </button>
-                        </Tooltip>
+                        <IconButton 
+                            tooltip={'AI edit suggestions'}
+                            onPointerDown={this.gptEdit}
+                            icon={<FontAwesomeIcon icon="pencil-alt" />}
+                            color={StrCast(Doc.UserDoc().userColor)}
+                        />
                     )}
-                    <Tooltip key="link" title={<div className="dash-tooltip">Find document to link to selected text</div>}>
-                        <button className="antimodeMenu-button link" onPointerDown={this.toggleLinkPopup}>
-                            <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(1.5)' }} icon={'search'} size="lg" />
-                            <FontAwesomeIcon style={{ position: 'absolute', transform: 'scale(0.5)', transformOrigin: 'top left', top: 12, left: 12 }} icon={'link'} size="lg" />
-                        </button>
-                    </Tooltip>
-                    <LinkPopup key="popup" showPopup={this._showLinkPopup} linkCreateAnchor={this.onMakeAnchor} />,
+                    <Popup 
+                        tooltip='Find document to link to selected text'
+                        type={Type.PRIM}
+                        icon={<FontAwesomeIcon icon={'search'} />}
+                        popup={<LinkPopup key="popup" linkCreateAnchor={this.onMakeAnchor} />}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />
                     {AnchorMenu.Instance.StartCropDrag === unimplementedFunction ? null : (
-                        <Tooltip key="crop" title={<div className="dash-tooltip">Click/Drag to create cropped image</div>}>
-                            <button className="antimodeMenu-button annotate" onPointerDown={this.cropDown} style={{ cursor: 'grab' }}>
-                                <FontAwesomeIcon icon="image" size="lg" />
-                            </button>
-                        </Tooltip>
+                        <IconButton 
+                            tooltip={'Click/Drag to create cropped image'}
+                            onPointerDown={this.cropDown}
+                            icon={<FontAwesomeIcon icon="image"/>}
+                            color={StrCast(Doc.UserDoc().userColor)}
+                        />
                     )}
                 </>
             ) : (
diff --git a/src/client/views/search/SearchBox.scss b/src/client/views/search/SearchBox.scss
index 5516cf205..a439aea3e 100644
--- a/src/client/views/search/SearchBox.scss
+++ b/src/client/views/search/SearchBox.scss
@@ -9,7 +9,6 @@
     background: none;
     z-index: 1000;
     padding: 0px;
-    overflow: scroll;
     cursor: default;
 
     .searchBox-bar {
@@ -22,7 +21,7 @@
         padding: 5px;
         top: 0px;
         position: sticky;
-        background: $light-gray;
+        overflow-y: scroll;
         border-bottom: $standard-border;
 
         .searchBox-type {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 12c25ca09..11f22ad5e 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -17,6 +17,7 @@ import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import './SearchBox.scss';
 import { fetchRecommendations } from '../newlightbox/utils';
 import { IRecommendation, Recommendation } from '../newlightbox/components';
+import { Colors } from '../global/globalEnums';
 
 const DAMPENING_FACTOR = 0.9;
 const MAX_ITERATIONS = 25;
@@ -528,7 +529,7 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
         ))
 
         return (
-            <div style={{ pointerEvents: 'all' }} className="searchBox-container">
+            <div className="searchBox-container" style={{pointerEvents: 'all', background: StrCast(Doc.UserDoc().userBackgroundColor)}}>
                 <div className="searchBox-bar">
                     {isLinkSearch ? null : (
                         <select name="type" id="searchBox-type" className="searchBox-type" onChange={this.onSelectChange}>
@@ -552,14 +553,14 @@ export class SearchBox extends ViewBoxBaseComponent<SearchBoxProps>() {
                     />
                 </div>
                 {resultsJSX.length > 0 && <div className="searchBox-results-container">
-                    <div className="section-header">
+                    <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
                         <div className="section-title">Results</div>
                         <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
                     </div>
                     <div className="searchBox-results-view">{resultsJSX}</div>
                 </div>}
                 {recommendationsJSX.length > 0 && <div className="searchBox-recommendations-container">
-                    <div className="section-header">
+                    <div className="section-header" style={{background: StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE)}}>
                         <div className="section-title">Recommendations</div>
                         <div className="section-subtitle">{`${validResults}` + ' result' + (validResults === 1 ? '' : 's')}</div>
                     </div>
diff --git a/src/client/views/selectedDoc/SelectedDocView.scss b/src/client/views/selectedDoc/SelectedDocView.scss
new file mode 100644
index 000000000..156dfc37b
--- /dev/null
+++ b/src/client/views/selectedDoc/SelectedDocView.scss
@@ -0,0 +1,3 @@
+.selectedDocView-container {
+    
+}
\ No newline at end of file
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
new file mode 100644
index 000000000..1c9e124a2
--- /dev/null
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -0,0 +1,47 @@
+import React = require('react');
+import { Doc } from "../../../fields/Doc";
+import { observer } from "mobx-react";
+import { computed } from "mobx";
+import { StrCast } from "../../../fields/Types";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Colors, ListBox } from 'browndash-components';
+import { DocumentManager } from '../../util/DocumentManager';
+import { DocFocusOptions } from '../nodes/DocumentView';
+
+export interface SelectedDocViewProps {
+    selectedDocs: Doc[];
+}
+
+@observer
+export class SelectedDocView extends React.Component<SelectedDocViewProps> {
+
+    @computed get selectedDocs() {
+        return this.props.selectedDocs;
+    }
+    
+
+    render() {
+        return <div className={`selectedDocView-container`}>
+            <ListBox
+                items={this.selectedDocs.map((doc) => {
+                    const icon = Doc.toIcon(doc);
+                    const iconEle = <FontAwesomeIcon size={'1x'} icon={icon} />;
+                    const text = StrCast(doc.title)
+                    const finished = () => {
+                        
+                    };
+                    const options: DocFocusOptions = {
+                        playAudio: false,
+                    };
+                    return {
+                        text: text,
+                        val: StrCast(doc._id),
+                        icon: iconEle,
+                        onClick: () => {DocumentManager.Instance.showDocument(doc, options, finished);}
+                    }
+                })}
+                color={Colors.WHITE}
+            />
+        </div>
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/selectedDoc/index.ts b/src/client/views/selectedDoc/index.ts
new file mode 100644
index 000000000..1f1db91f6
--- /dev/null
+++ b/src/client/views/selectedDoc/index.ts
@@ -0,0 +1 @@
+export * from './SelectedDocView'
\ No newline at end of file
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index b613a0e3e..1b0c6803c 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, IconButton, FontSize, Size, Type } from 'browndash-components';
+import { Button, IconButton, FontSize, Size, Type, isDark } from 'browndash-components';
 import { action, computed, observable, reaction } from 'mobx';
 import { Tooltip } from '@mui/material';
 import { observer } from 'mobx-react';
@@ -36,9 +36,10 @@ export class TopBar extends React.Component {
         });
     };
 
-    @observable textColor: string = Colors.LIGHT_GRAY;
+    @computed get color() { return StrCast(Doc.UserDoc().userColor, Colors.LIGHT_GRAY); }
+    @computed get variantColor() { return StrCast(Doc.UserDoc().userVariantColor, Colors.MEDIUM_BLUE); }
     @computed get backgroundColor() {
-        return PingManager.Instance.IsBeating ? Colors.DARK_GRAY : Colors.MEDIUM_GRAY;
+        return PingManager.Instance.IsBeating ? StrCast(Doc.UserDoc().userBackgroundColor, Colors.DARK_GRAY) : Colors.MEDIUM_GRAY;
     }
 
     @observable happyHeart: boolean = PingManager.Instance.IsBeating;
@@ -59,16 +60,16 @@ export class TopBar extends React.Component {
         return (
             <div className="topbar-left">
                 {Doc.ActiveDashboard ? (
-                    <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.textColor} />
+                    <IconButton onClick={this.navigateToHome} icon={<FontAwesomeIcon icon="home" />} color={this.color} />
                 ) : (
                     <div className="logo-container">
                         <img className="logo" src="/assets/medium-blue-light-blue-circle.png" alt="dash logo"></img>
-                        <span style={{ color: Colors.LIGHT_GRAY, fontWeight: 200 }}>brown</span>
-                        <span style={{ color: Colors.LIGHT_BLUE, fontWeight: 500 }}>dash</span>
+                        <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_GRAY : Colors.DARK_GRAY, fontWeight: 200 }}>brown</span>
+                        <span style={{ color: isDark(this.backgroundColor) ? Colors.LIGHT_BLUE : Colors.MEDIUM_BLUE, fontWeight: 500 }}>dash</span>
                     </div>
                 )}
                 {Doc.ActiveDashboard && (
-                    <Button text="Explore" tooltip="Browsing mode for directly navigating to documents" size={Size.SMALL} color={this.textColor} onClick={action(() => (MainView.Instance._exploreMode = !MainView.Instance._exploreMode))} />
+                    <Button text="Explore" tooltip="Browsing mode for directly navigating to documents" size={Size.SMALL} color={this.color} onClick={action(() => (MainView.Instance._exploreMode = !MainView.Instance._exploreMode))} />
                 )}
             </div>
         );
@@ -97,7 +98,7 @@ export class TopBar extends React.Component {
                     text={StrCast(Doc.ActiveDashboard.title)}
                     tooltip="Open Dashboards"
                     size={Size.SMALL}
-                    color={'white'}
+                    color={this.color}
                     style={{fontWeight: 700, fontSize: '1rem'}}
                     onClick={(e: React.MouseEvent) => {
                         const dashView = Doc.ActiveDashboard && DocumentManager.Instance.getDocumentView(Doc.ActiveDashboard);
@@ -118,7 +119,7 @@ export class TopBar extends React.Component {
                     <IconButton
                         tooltip="Work on a copy of the dashboard layout"
                         size={Size.SMALL}
-                        color={this.textColor}
+                        color={this.color}
                         onClick={async () => {
                             const batch = UndoManager.StartBatch('snapshot');
                             await DashboardView.snapshotDashboard();
@@ -142,23 +143,25 @@ export class TopBar extends React.Component {
                 {Doc.ActiveDashboard && <Button
                     text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
                     type={Type.TERT}
+                    color={this.variantColor}
                     onClick={() => {
                         SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                     }}
                     size={Size.SMALL}
                 />}
-                <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
-                <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={ReportManager.Instance.open} icon={<FaBug />} />
-                <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
-                <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={Colors.LIGHT_GRAY} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
+                <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
+                <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
+                <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
+                <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
                 <IconButton
                     size={Size.SMALL}
                     onClick={PingManager.Instance.showAlert}
+                    type={Type.TERT}
                     tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
                     color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
                     icon={<FontAwesomeIcon icon={this.happyHeart ? 'heart' : 'heart-broken'} />}
                 />
-                {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.textColor} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
+                {/* <Button text={'Logout'} borderRadius={5} hoverStyle={'gray'} backgroundColor={Colors.DARK_GRAY} color={this.color} fontSize={FontSize.SECONDARY} onClick={() => window.location.assign(Utils.prepend('/logout'))} /> */}
             </div>
         );
     }
@@ -168,8 +171,9 @@ export class TopBar extends React.Component {
             //TODO:glr Add support for light / dark mode
             <div style={{ 
                 pointerEvents: 'all',
-                color: this.textColor,
-                background: this.backgroundColor, 
+                color: this.color,
+                background: this.backgroundColor,
+                // borderColor: this.color
             }} className="topbar-container">
                 <div className="topbar-inner-container">
                     {this.topbarLeft}
-- 
cgit v1.2.3-70-g09d2


From 75a7c44f9615c4ac024403011a968f8b3038c500 Mon Sep 17 00:00:00 2001
From: Geireann Lindfield Roberts <60007097+geireann@users.noreply.github.com>
Date: Tue, 18 Jul 2023 01:00:46 -0400
Subject: added number inputs to right hand side

---
 package-lock.json                                  | 639 +++++++++++----------
 package.json                                       |   2 +-
 src/Utils.ts                                       |  16 +
 src/client/util/SharingManager.scss                |   1 +
 src/client/util/SharingManager.tsx                 |  16 +-
 src/client/views/DashboardView.tsx                 |   4 +-
 src/client/views/PropertiesButtons.tsx             |  46 --
 src/client/views/PropertiesView.scss               |   2 +-
 src/client/views/PropertiesView.tsx                |  90 ++-
 src/client/views/UndoStack.tsx                     |   6 +-
 src/client/views/nodes/FontIconBox/FontIconBox.tsx |   5 +-
 src/client/views/pdf/AnchorMenu.tsx                |  52 +-
 src/client/views/selectedDoc/SelectedDocView.tsx   |   2 +-
 src/client/views/topbar/TopBar.tsx                 |  15 +-
 14 files changed, 476 insertions(+), 420 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/package-lock.json b/package-lock.json
index d4facf59e..6d1071aeb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3270,7 +3270,7 @@
         "@types/bcrypt-nodejs": {
             "version": "0.0.30",
             "resolved": "https://registry.npmjs.org/@types/bcrypt-nodejs/-/bcrypt-nodejs-0.0.30.tgz",
-            "integrity": "sha512-gSWCu7EOXhcM0FYM8tanV0deaX1VM07sgBS8dSUmgnAQ5/3Xn6k+mWF+ZfE+c/OCW14IVnNdTOKcHgvL78oDFQ==",
+            "integrity": "sha1-TN2WtJKTs5MhIuS34pVD415rrlg=",
             "dev": true
         },
         "@types/bezier-js": {
@@ -4522,7 +4522,7 @@
         "@types/typescript": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz",
-            "integrity": "sha512-WMEWfMISiJ2QKyk5/dSdgL0ZwP//PZj0jmDU0hMh51FmLq4WIYzjlngsUQZXejQL+QtkXJUOGjb3G3UCvgZuSQ==",
+            "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=",
             "dev": true,
             "requires": {
                 "typescript": "*"
@@ -4837,7 +4837,7 @@
                 "textarea-caret": {
                     "version": "3.0.2",
                     "resolved": "https://registry.npmjs.org/textarea-caret/-/textarea-caret-3.0.2.tgz",
-                    "integrity": "sha512-gRzeti2YS4did7UJnPQ47wrjD+vp+CJIe9zbsu0bJ987d8QVLvLNG9757rqiQTIy4hGIeFauTTJt5Xkn51UkXg=="
+                    "integrity": "sha1-82DEhpmqGr9xhoCkOjGoUGZcLK8="
                 }
             }
         },
@@ -4856,7 +4856,7 @@
         "Base64": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz",
-            "integrity": "sha512-reGEWshDmTDQDsCec/HduOO9Wyj6yMOupMfhIf3ugN1TDlK2NQW4DDJSqNNtp380SNcvRfXtO8HSCQot0d0SMw=="
+            "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg="
         },
         "D": {
             "version": "1.0.0",
@@ -4936,7 +4936,7 @@
         "after": {
             "version": "0.8.2",
             "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
-            "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA=="
+            "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
         },
         "agent-base": {
             "version": "6.0.2",
@@ -5105,7 +5105,7 @@
         "any-promise": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-            "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="
+            "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
         },
         "anymatch": {
             "version": "2.0.0",
@@ -5258,7 +5258,7 @@
         "arr-diff": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
-            "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA=="
+            "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA="
         },
         "arr-flatten": {
             "version": "1.1.0",
@@ -5268,7 +5268,7 @@
         "arr-union": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
-            "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q=="
+            "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
         },
         "array-back": {
             "version": "2.0.0",
@@ -5370,7 +5370,7 @@
         "array-flatten": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
-            "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+            "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
         },
         "array-includes": {
             "version": "3.1.6",
@@ -5403,7 +5403,7 @@
         "array-unique": {
             "version": "0.3.2",
             "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
-            "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ=="
+            "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
         },
         "array.prototype.flat": {
             "version": "1.3.1",
@@ -5480,7 +5480,7 @@
         "assert-plus": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-            "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw=="
+            "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
         },
         "assertion-error": {
             "version": "1.1.0",
@@ -5490,7 +5490,7 @@
         "assign-symbols": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
-            "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw=="
+            "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
         },
         "ast-types-flow": {
             "version": "0.0.7",
@@ -5520,7 +5520,7 @@
         "async-foreach": {
             "version": "0.1.3",
             "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
-            "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA=="
+            "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
         },
         "async-limiter": {
             "version": "1.0.1",
@@ -5531,7 +5531,7 @@
         "asynckit": {
             "version": "0.4.0",
             "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-            "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+            "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
         },
         "atob": {
             "version": "2.1.2",
@@ -5581,7 +5581,7 @@
         "aws-sign2": {
             "version": "0.7.0",
             "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-            "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA=="
+            "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
         },
         "aws4": {
             "version": "1.12.0",
@@ -5659,7 +5659,7 @@
         "babel": {
             "version": "6.23.0",
             "resolved": "https://registry.npmjs.org/babel/-/babel-6.23.0.tgz",
-            "integrity": "sha512-ZDcCaI8Vlct8PJ3DvmyqUz+5X2Ylz3ZuuItBe/74yXosk2dwyVo/aN7MCJ8HJzhnnJ+6yP4o+lDgG9MBe91DLA=="
+            "integrity": "sha1-0NHn2APpdHZb7qMjLU4VPA77kPQ="
         },
         "babel-code-frame": {
             "version": "6.26.0",
@@ -5818,12 +5818,12 @@
         "babel-plugin-syntax-jsx": {
             "version": "6.18.0",
             "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
-            "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw=="
+            "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
         },
         "babel-runtime": {
             "version": "6.26.0",
             "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
-            "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
+            "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
             "requires": {
                 "core-js": "^2.4.0",
                 "regenerator-runtime": "^0.11.0"
@@ -5867,7 +5867,7 @@
         "backo2": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
-            "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA=="
+            "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
         },
         "bail": {
             "version": "2.0.2",
@@ -5896,7 +5896,7 @@
                 "define-property": {
                     "version": "1.0.0",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-                    "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+                    "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
                         "is-descriptor": "^1.0.0"
                     }
@@ -5932,12 +5932,12 @@
         "base16": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/base16/-/base16-1.0.0.tgz",
-            "integrity": "sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ=="
+            "integrity": "sha1-4pf2DX7BAUp6lxo568ipjAtoHnA="
         },
         "base64-arraybuffer": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
-            "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg=="
+            "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
         },
         "base64-js": {
             "version": "1.5.1",
@@ -5957,18 +5957,18 @@
         "batch": {
             "version": "0.6.1",
             "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
-            "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+            "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
             "dev": true
         },
         "bcrypt-nodejs": {
             "version": "0.0.3",
             "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz",
-            "integrity": "sha512-NmTbLm867btBHCBZ222FQXkQKzecB0KG6pTXFa6NeTVZaSnLfCsx7EK2PL3J+kX8xJThUquEBbhimRCKKZX9zA=="
+            "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs="
         },
         "bcrypt-pbkdf": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-            "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+            "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
             "requires": {
                 "tweetnacl": "^0.14.3"
             }
@@ -5981,7 +5981,7 @@
         "bezier-curve": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/bezier-curve/-/bezier-curve-1.0.0.tgz",
-            "integrity": "sha512-h6uZJ6qdFfswS1rIRericgouhTeiVi/MnH10OKtCu2IZzXa+ZcjaxRLHY4u/evRsJcxYbbiNkgWQj2Z4UIcpEQ=="
+            "integrity": "sha1-o9+v6rEqlMRicw1QeYxSqEBdc3k="
         },
         "bezier-js": {
             "version": "4.1.1",
@@ -6120,7 +6120,7 @@
         "boolbase": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
-            "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+            "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
         },
         "bootstrap": {
             "version": "4.6.2",
@@ -6182,7 +6182,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -6198,9 +6198,9 @@
             }
         },
         "browndash-components": {
-            "version": "0.0.76",
-            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.76.tgz",
-            "integrity": "sha512-2ZrDNGxbXnmqRSBifCn6+czz/LqeuyZwSsnRj73Wmo9OOKvYIneGZE17/aFkAl76rXdVmZCcfBdKKBcwEYwNHQ==",
+            "version": "0.0.78",
+            "resolved": "https://registry.npmjs.org/browndash-components/-/browndash-components-0.0.78.tgz",
+            "integrity": "sha512-kW9RuemZEA77KPc3zAE1/PnwDOP0gjqfP2xBDkJyDLvWIXSUUDTDJBCBxvFNOjU83OyZWaDxhrFtSgFnSKX4LQ==",
             "requires": {
                 "@emotion/react": "^11.11.1",
                 "@emotion/styled": "^11.11.0",
@@ -6730,7 +6730,7 @@
         "browser-assert": {
             "version": "1.2.1",
             "resolved": "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz",
-            "integrity": "sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ=="
+            "integrity": "sha1-mqpaKox0aFwq4Fv+Ru/WBvBowgA="
         },
         "browser-process-hrtime": {
             "version": "1.0.0",
@@ -6774,7 +6774,7 @@
         "buffer-crc32": {
             "version": "0.2.13",
             "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-            "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="
+            "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
         },
         "buffer-equal-constant-time": {
             "version": "1.0.1",
@@ -6800,7 +6800,7 @@
         "built-in-math-eval": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/built-in-math-eval/-/built-in-math-eval-0.3.0.tgz",
-            "integrity": "sha512-5XD5cujru60ooKJ4sGZqoH5v2Xvgw7ezV54gJX/OnPkgDKoH3BnlMEi8xW6hl8xaEjxKHebgrsawroeZnGwIMA==",
+            "integrity": "sha1-JA3CHLOJQ5WIxhxGDrAHZJfvxBw=",
             "requires": {
                 "math-codegen": "^0.3.5"
             }
@@ -6923,7 +6923,7 @@
         "caller-callsite": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
-            "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==",
+            "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
             "requires": {
                 "callsites": "^2.0.0"
             },
@@ -6931,14 +6931,14 @@
                 "callsites": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
-                    "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ=="
+                    "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
                 }
             }
         },
         "caller-path": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
-            "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==",
+            "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
             "requires": {
                 "caller-callsite": "^2.0.0"
             }
@@ -7006,7 +7006,7 @@
         "caseless": {
             "version": "0.12.0",
             "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-            "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+            "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
         },
         "ccount": {
             "version": "2.0.1",
@@ -7083,12 +7083,12 @@
         "check-error": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
-            "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA=="
+            "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
         },
         "child_process": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/child_process/-/child_process-1.0.2.tgz",
-            "integrity": "sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g=="
+            "integrity": "sha1-sffn/HPSXn/R1FWtyU4UODAYK1o="
         },
         "chokidar": {
             "version": "2.1.8",
@@ -7137,7 +7137,7 @@
         "clamp": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/clamp/-/clamp-1.0.1.tgz",
-            "integrity": "sha512-kgMuFyE78OC6Dyu3Dy7vcx4uy97EIbVxJB/B0eJ3bUNAkwdNcxYzgKltnyADiYwsR7SEqkkUPsEUT//OVS6XMA=="
+            "integrity": "sha1-ZqDmQBGBbjcZaCj9yMjBRzEshjQ="
         },
         "class-transformer": {
             "version": "0.2.3",
@@ -7158,7 +7158,7 @@
                 "define-property": {
                     "version": "0.2.5",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-                    "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+                    "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
                         "is-descriptor": "^0.1.0"
                     }
@@ -7208,7 +7208,7 @@
         "clipboard": {
             "version": "1.7.1",
             "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
-            "integrity": "sha512-smkaRaIQsrnKN1F3wd1/vY9Q+DeR4L8ZCXKeHCFC2j8RZuSBbuImcLdnIO4GTxmzJxQuDGNKkyfpGoPW7Ua5bQ==",
+            "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
             "requires": {
                 "good-listener": "^1.2.2",
                 "select": "^1.1.2",
@@ -7283,7 +7283,7 @@
         "clj-fuzzy": {
             "version": "0.3.3",
             "resolved": "https://registry.npmjs.org/clj-fuzzy/-/clj-fuzzy-0.3.3.tgz",
-            "integrity": "sha512-9cyh9A8+OphDZeKIG21MgyDHWDkWxTvagwvFLVjtdi6eToFENF7iDLlKwhHrnBQRSQwprKNhazG053nE/UgwfQ=="
+            "integrity": "sha1-seU0MJHFIC28UlMoY+HEp4RX8D0="
         },
         "clone-deep": {
             "version": "4.0.1",
@@ -7318,7 +7318,7 @@
         "collection-visit": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
-            "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
+            "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
             "requires": {
                 "map-visit": "^1.0.0",
                 "object-visit": "^1.0.0"
@@ -7344,7 +7344,7 @@
         "color-name": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-            "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+            "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
         },
         "color-string": {
             "version": "1.9.1",
@@ -7413,7 +7413,7 @@
         "component-bind": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
-            "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw=="
+            "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
         },
         "component-emitter": {
             "version": "1.3.0",
@@ -7423,7 +7423,7 @@
         "component-inherit": {
             "version": "0.0.3",
             "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
-            "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA=="
+            "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
         },
         "compress-commons": {
             "version": "2.1.1",
@@ -7479,7 +7479,7 @@
                 "bytes": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
-                    "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
+                    "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
                     "dev": true
                 },
                 "debug": {
@@ -7494,7 +7494,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
                     "dev": true
                 }
             }
@@ -7502,7 +7502,7 @@
         "concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
         "concat-stream": {
             "version": "1.6.2",
@@ -7568,7 +7568,7 @@
         "connect-flash": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz",
-            "integrity": "sha512-2rcfELQt/ZMP+SM/pG8PyhJRaLKp+6Hk2IUBNkEit09X+vwn3QsAL3ZbYtxUn7NVPzbMTSLRDhqe0B/eh30RYA=="
+            "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA="
         },
         "connect-history-api-fallback": {
             "version": "1.6.0",
@@ -7626,7 +7626,7 @@
         "console-control-strings": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-            "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
+            "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
         },
         "constantinople": {
             "version": "3.1.2",
@@ -7707,7 +7707,7 @@
         "cookie-signature": {
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
-            "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+            "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
         },
         "cookies": {
             "version": "0.8.0",
@@ -7752,7 +7752,7 @@
         "copy-descriptor": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
-            "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw=="
+            "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
         },
         "copy-webpack-plugin": {
             "version": "4.6.0",
@@ -7969,7 +7969,7 @@
         "crypto-random-string": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
-            "integrity": "sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg=="
+            "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4="
         },
         "css-box-model": {
             "version": "1.2.1",
@@ -7982,7 +7982,7 @@
         "css-color-keywords": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
-            "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg=="
+            "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
         },
         "css-in-js-utils": {
             "version": "2.0.1",
@@ -8151,7 +8151,7 @@
         "custom-event": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
-            "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg=="
+            "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU="
         },
         "cyclist": {
             "version": "1.0.1",
@@ -8159,6 +8159,16 @@
             "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
             "dev": true
         },
+        "d": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
+            "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
+            "dev": true,
+            "requires": {
+                "es5-ext": "^0.10.50",
+                "type": "^1.0.1"
+            }
+        },
         "d3": {
             "version": "7.8.4",
             "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz",
@@ -8438,7 +8448,7 @@
         "dashdash": {
             "version": "1.14.1",
             "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-            "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+            "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
             "requires": {
                 "assert-plus": "^1.0.0"
             }
@@ -8490,7 +8500,7 @@
         "de-indent": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
-            "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg=="
+            "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
         },
         "debounce": {
             "version": "1.2.1",
@@ -8508,7 +8518,7 @@
         "decamelize": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-            "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
+            "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
         },
         "decimal.js-light": {
             "version": "2.5.1",
@@ -8747,7 +8757,7 @@
         "delayed-stream": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-            "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
+            "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
         },
         "delegate": {
             "version": "3.2.0",
@@ -8757,7 +8767,7 @@
         "delegates": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-            "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
+            "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
         },
         "denque": {
             "version": "1.5.1",
@@ -8860,7 +8870,7 @@
                 "import-fresh": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
-                    "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==",
+                    "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
                     "requires": {
                         "caller-path": "^2.0.0",
                         "resolve-from": "^3.0.0"
@@ -8895,7 +8905,7 @@
                 "parse-json": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
-                    "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+                    "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
                     "requires": {
                         "error-ex": "^1.3.1",
                         "json-parse-better-errors": "^1.0.1"
@@ -8909,7 +8919,7 @@
                 "resolve-from": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
-                    "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw=="
+                    "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
                 },
                 "string-width": {
                     "version": "4.2.3",
@@ -8981,7 +8991,7 @@
         "deps-regex": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/deps-regex/-/deps-regex-0.1.4.tgz",
-            "integrity": "sha512-3tzwGYogSJi8HoG93R5x9NrdefZQOXgHgGih/7eivloOq6yC6O+yoFxZnkgP661twvfILONfoKRdF9GQOGx2RA=="
+            "integrity": "sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ="
         },
         "dequal": {
             "version": "2.0.3",
@@ -9186,7 +9196,7 @@
         "double-bits": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/double-bits/-/double-bits-1.1.1.tgz",
-            "integrity": "sha512-BCLEIBq0O/DWoA7BsCu/R+RP0ZXiowP8BhtJT3qeuuQEBpnS8LK/Wo6UTJQv6v8mK1fj8n90YziHLwGdM5whSg=="
+            "integrity": "sha1-WKu6RUlNpND6Nrc60RoobJGEscY="
         },
         "duplexer3": {
             "version": "0.1.5",
@@ -9234,7 +9244,7 @@
         "ecc-jsbn": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-            "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+            "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
             "requires": {
                 "jsbn": "~0.1.0",
                 "safer-buffer": "^2.1.0"
@@ -9251,7 +9261,7 @@
         "ee-first": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-            "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+            "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
         },
         "electron-to-chromium": {
             "version": "1.4.454",
@@ -9280,7 +9290,7 @@
         "encodeurl": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
-            "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
+            "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
         },
         "encoding": {
             "version": "0.1.13",
@@ -9355,7 +9365,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 },
                 "ws": {
                     "version": "7.4.6",
@@ -9539,6 +9549,28 @@
                 "is-symbol": "^1.0.2"
             }
         },
+        "es5-ext": {
+            "version": "0.10.62",
+            "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
+            "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
+            "dev": true,
+            "requires": {
+                "es6-iterator": "^2.0.3",
+                "es6-symbol": "^3.1.3",
+                "next-tick": "^1.1.0"
+            }
+        },
+        "es6-iterator": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+            "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
+            "dev": true,
+            "requires": {
+                "d": "1",
+                "es5-ext": "^0.10.35",
+                "es6-symbol": "^3.1.1"
+            }
+        },
         "es6-promise": {
             "version": "3.2.1",
             "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz",
@@ -9550,6 +9582,7 @@
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
             "dev": true,
             "requires": {
+                "d": "^1.0.1",
                 "ext": "^1.1.2"
             }
         },
@@ -9561,12 +9594,12 @@
         "escape-html": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
-            "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+            "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
         },
         "escape-string-regexp": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
+            "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
         },
         "escodegen": {
             "version": "1.14.3",
@@ -10879,7 +10912,7 @@
         "etag": {
             "version": "1.8.1",
             "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
-            "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
+            "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
         },
         "event-target-shim": {
             "version": "5.0.1",
@@ -10951,7 +10984,7 @@
         "exeq": {
             "version": "2.4.0",
             "resolved": "https://registry.npmjs.org/exeq/-/exeq-2.4.0.tgz",
-            "integrity": "sha512-B648qbDS00nQZv9UQGLT5RbZm/5dNBX10F8oWeXcgpFHSLm1249u95t/3sn2wXdQjLhlF+edAECdshFtSr1K0Q==",
+            "integrity": "sha1-Td8qaEZIxCeteZNJzzO9dTWPiEo=",
             "requires": {
                 "bluebird": "^3.0.3",
                 "native-or-bluebird": "^1.2.0"
@@ -10960,7 +10993,7 @@
         "exif": {
             "version": "0.6.0",
             "resolved": "https://registry.npmjs.org/exif/-/exif-0.6.0.tgz",
-            "integrity": "sha512-gEwM4uanNMfLnDNKclZ7jPEA99E3rpy4ntoS6QW8u6murZjl1o8qRaPdMoC46Syg3d9/QaET0bYKhWlTwJCPgg==",
+            "integrity": "sha1-YKYmaAdlQst+T1cZnUrG830sX0o=",
             "requires": {
                 "debug": "^2.2"
             },
@@ -10976,7 +11009,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 }
             }
         },
@@ -10988,7 +11021,7 @@
         "expand-brackets": {
             "version": "2.1.4",
             "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
-            "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
+            "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
             "requires": {
                 "debug": "^2.3.3",
                 "define-property": "^0.2.5",
@@ -11010,7 +11043,7 @@
                 "define-property": {
                     "version": "0.2.5",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-                    "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+                    "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
                         "is-descriptor": "^0.1.0"
                     }
@@ -11018,7 +11051,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -11026,7 +11059,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 }
             }
         },
@@ -11109,7 +11142,7 @@
         "express-flash": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/express-flash/-/express-flash-0.0.2.tgz",
-            "integrity": "sha512-QVUR0ZZRCaa8+iPHoUQaQJrQWcQuK/Q+19M7IUIdIEtvwhrA/ifHT7y1CVJI41YfGiOQnbGtn3uvd2vOdgu58A==",
+            "integrity": "sha1-I9GovPP5DXB5KOSJ+Whp7K0KzaI=",
             "requires": {
                 "connect-flash": "0.1.x"
             }
@@ -11166,7 +11199,7 @@
         "expressjs": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/expressjs/-/expressjs-1.0.1.tgz",
-            "integrity": "sha512-eFnQ5bMJxTZ29XwRJPV8ee/OURBBMS6Fm+b5rvMMEyz6u2IxPEh2SRzMZt9WvgnV+SMLmnzkALE1DnGG1HxJCw=="
+            "integrity": "sha1-IgMoRpoY31rWFeK3oM6ZXxf7ru8="
         },
         "ext": {
             "version": "1.7.0",
@@ -11193,7 +11226,7 @@
         "extend-shallow": {
             "version": "3.0.2",
             "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
-            "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+            "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
             "requires": {
                 "assign-symbols": "^1.0.0",
                 "is-extendable": "^1.0.1"
@@ -11257,7 +11290,7 @@
                 "define-property": {
                     "version": "1.0.0",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-                    "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+                    "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
                         "is-descriptor": "^1.0.0"
                     }
@@ -11265,7 +11298,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -11335,7 +11368,7 @@
         "extsprintf": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-            "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g=="
+            "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
         },
         "fast-deep-equal": {
             "version": "3.1.3",
@@ -11361,7 +11394,7 @@
         "fast-levenshtein": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-            "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+            "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
             "dev": true
         },
         "fast-text-encoding": {
@@ -11416,7 +11449,7 @@
         "fd-slicer": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
-            "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+            "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
             "requires": {
                 "pend": "~1.2.0"
             }
@@ -11424,7 +11457,7 @@
         "ffmpeg": {
             "version": "0.0.4",
             "resolved": "https://registry.npmjs.org/ffmpeg/-/ffmpeg-0.0.4.tgz",
-            "integrity": "sha512-3TgWUJJlZGQn+crJFyhsO/oNeRRnGTy6GhgS98oUCIfZrOW5haPPV7DUfOm3xJcHr5q3TJpjk2GudPutrNisRA==",
+            "integrity": "sha1-HEYN+OfaUSf2LO70v6BsWciWMMs=",
             "requires": {
                 "when": ">= 0.0.1"
             }
@@ -11471,7 +11504,7 @@
         "fill-range": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
-            "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+            "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
             "requires": {
                 "extend-shallow": "^2.0.1",
                 "is-number": "^3.0.0",
@@ -11482,7 +11515,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -11492,7 +11525,7 @@
         "filter-obj": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz",
-            "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ=="
+            "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs="
         },
         "finalhandler": {
             "version": "1.2.0",
@@ -11526,7 +11559,7 @@
         "find": {
             "version": "0.1.7",
             "resolved": "https://registry.npmjs.org/find/-/find-0.1.7.tgz",
-            "integrity": "sha512-jPrupTOe/pO//3a9Ty2o4NqQCp0L46UG+swUnfFtdmtQVN8pEltKpAqR7Nuf6vWn0GBXx5w+R1MyZzqwjEIqdA==",
+            "integrity": "sha1-yGyHrxqxjyIrvjjeyGy8dg0Wpvs=",
             "requires": {
                 "traverse-chain": "~0.1.0"
             }
@@ -11675,7 +11708,7 @@
         "fluent-ffmpeg": {
             "version": "2.1.2",
             "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.2.tgz",
-            "integrity": "sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==",
+            "integrity": "sha1-yVLeIkD4EuvaCqgAbXd27irPfXQ=",
             "requires": {
                 "async": ">=0.2.9",
                 "which": "^1.1.1"
@@ -11758,12 +11791,12 @@
         "for-in": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
-            "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="
+            "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
         },
         "forever-agent": {
             "version": "0.6.1",
             "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-            "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw=="
+            "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
         },
         "fork-ts-checker-webpack-plugin": {
             "version": "1.6.0",
@@ -11817,7 +11850,7 @@
         "fragment-cache": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
-            "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
+            "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
             "requires": {
                 "map-cache": "^0.2.2"
             }
@@ -11825,7 +11858,7 @@
         "fresh": {
             "version": "0.5.2",
             "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
-            "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
+            "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
         },
         "from2": {
             "version": "2.3.0",
@@ -11941,7 +11974,7 @@
         "fs.realpath": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+            "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
         },
         "fsevents": {
             "version": "1.2.13",
@@ -12119,7 +12152,7 @@
         "get-func-name": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
-            "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig=="
+            "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
         },
         "get-intrinsic": {
             "version": "1.2.0",
@@ -12163,12 +12196,12 @@
         "get-value": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
-            "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA=="
+            "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
         },
         "getpass": {
             "version": "0.1.7",
             "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-            "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+            "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
             "requires": {
                 "assert-plus": "^1.0.0"
             }
@@ -12295,7 +12328,7 @@
         "golden-layout": {
             "version": "1.5.9",
             "resolved": "https://registry.npmjs.org/golden-layout/-/golden-layout-1.5.9.tgz",
-            "integrity": "sha512-iBXDQCXOTgUEQJo96zPbjDoy5bRIk9XW5l+q+pDgLnIyReqaa1aiQctNud4epsskyLt952BG521dew5Z1liSxA==",
+            "integrity": "sha1-o5vB9qZ+b4hreXwBbdkk6UJrp38=",
             "requires": {
                 "jquery": "*"
             }
@@ -12303,7 +12336,7 @@
         "good-listener": {
             "version": "1.2.2",
             "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
-            "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==",
+            "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
             "requires": {
                 "delegate": "^3.1.2"
             }
@@ -12482,7 +12515,7 @@
         "har-schema": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-            "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q=="
+            "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
         },
         "har-validator": {
             "version": "5.1.5",
@@ -12532,19 +12565,19 @@
                 "isarray": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
-                    "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ=="
+                    "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
                 }
             }
         },
         "has-cors": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
-            "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA=="
+            "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
         },
         "has-flag": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
+            "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
         },
         "has-property-descriptors": {
             "version": "1.0.0",
@@ -12575,12 +12608,12 @@
         "has-unicode": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-            "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
+            "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
         },
         "has-value": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
-            "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
+            "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
             "requires": {
                 "get-value": "^2.0.6",
                 "has-values": "^1.0.0",
@@ -12590,7 +12623,7 @@
         "has-values": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
-            "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
+            "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
             "requires": {
                 "is-number": "^3.0.0",
                 "kind-of": "^4.0.0"
@@ -12604,7 +12637,7 @@
                 "kind-of": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
-                    "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
+                    "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -12707,7 +12740,7 @@
         "hpack.js": {
             "version": "2.1.6",
             "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
-            "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==",
+            "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
             "dev": true,
             "requires": {
                 "inherits": "^2.0.1",
@@ -12736,7 +12769,7 @@
         "html": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/html/-/html-1.0.0.tgz",
-            "integrity": "sha512-lw/7YsdKiP3kk5PnR1INY17iJuzdAtJewxr14ozKJWbbR97znovZ0mh+WEMZ8rjc3lgTK+ID/htTjuyGKB52Kw==",
+            "integrity": "sha1-pUT6nqVJK/s6LMqCEKEL57WvH2E=",
             "requires": {
                 "concat-stream": "^1.4.7"
             }
@@ -12819,7 +12852,7 @@
         "http-browserify": {
             "version": "1.7.0",
             "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz",
-            "integrity": "sha512-Irf/LJXmE3cBzU1eaR4+NEX6bmVLqt1wkmDiA7kBwH7zmb0D8kBAXsDmQ88hhj/qv9iEZKlyGx/hrMcFi8sOHw==",
+            "integrity": "sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=",
             "requires": {
                 "Base64": "~0.2.0",
                 "inherits": "~2.0.1"
@@ -12833,7 +12866,7 @@
         "http-deceiver": {
             "version": "1.2.7",
             "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
-            "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==",
+            "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
             "dev": true
         },
         "http-errors": {
@@ -12880,7 +12913,7 @@
         "http-signature": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-            "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+            "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
             "requires": {
                 "assert-plus": "^1.0.0",
                 "jsprim": "^1.2.2",
@@ -12899,12 +12932,12 @@
         "https": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz",
-            "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg=="
+            "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q="
         },
         "https-browserify": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
-            "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg=="
+            "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM="
         },
         "https-proxy-agent": {
             "version": "5.0.1",
@@ -12956,7 +12989,7 @@
         "icss-replace-symbols": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
-            "integrity": "sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==",
+            "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
             "dev": true
         },
         "icss-utils": {
@@ -12988,7 +13021,7 @@
         "ignore-by-default": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
-            "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA=="
+            "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk="
         },
         "iink-js": {
             "version": "1.5.4",
@@ -13032,7 +13065,7 @@
         "image-size-stream": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/image-size-stream/-/image-size-stream-1.1.0.tgz",
-            "integrity": "sha512-N505B5FSy2Xf5l/Haef+99TwfJqTu40hnU560+rC0Cm6cxtwVz2yRFh9WpOk1YEjfv3dI0PgVYAH0hmXQmjDcw==",
+            "integrity": "sha1-Ivou2mbG31AQh0bacUkmSy0l+Gs=",
             "requires": {
                 "image-size": "github:netroy/image-size#da2c863807a3e9602617bdd357b0de3ab4a064c1",
                 "readable-stream": "^1.0.33",
@@ -13046,12 +13079,12 @@
                 "isarray": {
                     "version": "0.0.1",
                     "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
-                    "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
+                    "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
                 },
                 "readable-stream": {
                     "version": "1.1.14",
                     "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
-                    "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+                    "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
                     "requires": {
                         "core-util-is": "~1.0.0",
                         "inherits": "~2.0.1",
@@ -13062,14 +13095,14 @@
                 "string_decoder": {
                     "version": "0.10.31",
                     "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
-                    "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+                    "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
                 }
             }
         },
         "immediate": {
             "version": "3.0.6",
             "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
-            "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+            "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
         },
         "import-fresh": {
             "version": "3.3.0",
@@ -13097,7 +13130,7 @@
         "imurmurhash": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-            "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
+            "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
         },
         "in-publish": {
             "version": "2.0.1",
@@ -13115,12 +13148,12 @@
         "indexof": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-            "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg=="
+            "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
         },
         "inflight": {
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+            "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
             "requires": {
                 "once": "^1.3.0",
                 "wrappy": "1"
@@ -13137,7 +13170,7 @@
                 "camelcase": {
                     "version": "4.1.0",
                     "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
-                    "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw=="
+                    "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
                 }
             }
         },
@@ -13491,7 +13524,7 @@
         "is-accessor-descriptor": {
             "version": "0.1.6",
             "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
-            "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==",
+            "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
             "requires": {
                 "kind-of": "^3.0.2"
             },
@@ -13504,7 +13537,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -13533,7 +13566,7 @@
         "is-arrayish": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-            "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+            "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
         },
         "is-bigint": {
             "version": "1.0.4",
@@ -13589,7 +13622,7 @@
         "is-data-descriptor": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
-            "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==",
+            "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
             "requires": {
                 "kind-of": "^3.0.2"
             },
@@ -13602,7 +13635,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -13637,7 +13670,7 @@
         "is-directory": {
             "version": "0.3.1",
             "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
-            "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw=="
+            "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
         },
         "is-expression": {
             "version": "3.0.0",
@@ -13663,7 +13696,7 @@
         "is-extglob": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-            "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+            "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
         },
         "is-finite": {
             "version": "1.1.0",
@@ -13673,7 +13706,7 @@
         "is-fullwidth-code-point": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-            "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w=="
+            "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
         },
         "is-generator-function": {
             "version": "1.0.10",
@@ -13694,7 +13727,7 @@
         "is-in-browser": {
             "version": "1.1.3",
             "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz",
-            "integrity": "sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g=="
+            "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU="
         },
         "is-installed-globally": {
             "version": "0.1.0",
@@ -13724,7 +13757,7 @@
         "is-number": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
-            "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+            "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
             "requires": {
                 "kind-of": "^3.0.2"
             },
@@ -13737,7 +13770,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -13875,7 +13908,7 @@
         "is-typedarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-            "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+            "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
         },
         "is-url": {
             "version": "1.2.4",
@@ -13930,17 +13963,17 @@
         "isarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+            "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
         },
         "isexe": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-            "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+            "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
         },
         "isobject": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
-            "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
+            "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
         },
         "isomorphic-fetch": {
             "version": "2.2.1",
@@ -13965,7 +13998,7 @@
         "isstream": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-            "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+            "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
         },
         "its-set": {
             "version": "1.2.3",
@@ -14047,7 +14080,7 @@
         "jsbn": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-            "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+            "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
         },
         "jsdom": {
             "version": "15.2.1",
@@ -14173,7 +14206,7 @@
         "json-css": {
             "version": "1.5.6",
             "resolved": "https://registry.npmjs.org/json-css/-/json-css-1.5.6.tgz",
-            "integrity": "sha512-B/0T0OxZH9tSb93tXV6VOYtXqrPz/Vgz2QrCT/4NXen8HGElYkYr9V+8IrSVTMj/ftxa8cG1kcu7f3iAMlaFlQ=="
+            "integrity": "sha1-65ZPg0ouTqobwvaY/12wB6JsfAA="
         },
         "json-parse-better-errors": {
             "version": "1.0.2",
@@ -14204,7 +14237,7 @@
         "json-stringify-safe": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-            "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+            "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
         },
         "json5": {
             "version": "1.0.2",
@@ -14456,7 +14489,7 @@
         "klaw": {
             "version": "1.3.1",
             "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
-            "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==",
+            "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
             "requires": {
                 "graceful-fs": "^4.1.9"
             }
@@ -14601,22 +14634,22 @@
         "lodash._getnative": {
             "version": "3.9.1",
             "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
-            "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA=="
+            "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
         },
         "lodash.chunk": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz",
-            "integrity": "sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w=="
+            "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw="
         },
         "lodash.curry": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
-            "integrity": "sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA=="
+            "integrity": "sha1-JI42By7ekGUB11lmIAqG2riyMXA="
         },
         "lodash.debounce": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-3.1.1.tgz",
-            "integrity": "sha512-lcmJwMpdPAtChA4hfiwxTtgFeNAaow701wWUgVUqeD0XJF7vMXIN+bu/2FJSGxT0NUbZy9g9VFrlOFfPjl+0Ew==",
+            "integrity": "sha1-gSIRw3ipTMKdWqTjNGzwv846ffU=",
             "requires": {
                 "lodash._getnative": "^3.0.0"
             }
@@ -14624,42 +14657,42 @@
         "lodash.defaults": {
             "version": "4.2.0",
             "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
-            "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
+            "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw="
         },
         "lodash.difference": {
             "version": "4.5.0",
             "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz",
-            "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA=="
+            "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw="
         },
         "lodash.flatten": {
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
-            "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="
+            "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
         },
         "lodash.flow": {
             "version": "3.5.0",
             "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
-            "integrity": "sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw=="
+            "integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o="
         },
         "lodash.get": {
             "version": "4.4.2",
             "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
-            "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+            "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
         },
         "lodash.isequal": {
             "version": "4.5.0",
             "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
-            "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+            "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
         },
         "lodash.isplainobject": {
             "version": "4.0.6",
             "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
-            "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="
+            "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
         },
         "lodash.memoize": {
             "version": "4.1.2",
             "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
-            "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
+            "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
         },
         "lodash.merge": {
             "version": "4.6.2",
@@ -14680,12 +14713,12 @@
         "lodash.throttle": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
-            "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+            "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
         },
         "lodash.union": {
             "version": "4.6.0",
             "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
-            "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw=="
+            "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
         },
         "log-symbols": {
             "version": "2.2.0",
@@ -14841,7 +14874,7 @@
         "map-cache": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
-            "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="
+            "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8="
         },
         "map-obj": {
             "version": "1.0.1",
@@ -14851,7 +14884,7 @@
         "map-visit": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
-            "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
+            "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
             "requires": {
                 "object-visit": "^1.0.0"
             }
@@ -14901,7 +14934,7 @@
         "math-codegen": {
             "version": "0.3.5",
             "resolved": "https://registry.npmjs.org/math-codegen/-/math-codegen-0.3.5.tgz",
-            "integrity": "sha512-SsFYMv33FxMKYxI1PBiaZT+8AeDITK+k/PKhbHNlOPHIz5FIPF4wy78yWqanN6luXdsXENUZgCIC6xH6bfUq1g==",
+            "integrity": "sha1-R5nuRnfe0Ud2bQA8ykt4ee3UDMo=",
             "requires": {
                 "extend": "^3.0.0",
                 "mr-parser": "^0.2.1"
@@ -14910,7 +14943,7 @@
         "mathquill": {
             "version": "0.10.1-a",
             "resolved": "https://registry.npmjs.org/mathquill/-/mathquill-0.10.1-a.tgz",
-            "integrity": "sha512-snSAEwAtwdwBFSor+nVBnWWQtTw67kgAgKMyAIxuz4ZPboy0qkWZmd7BL3lfOXp/INihhRlU1PcfaAtDaRhmzA==",
+            "integrity": "sha1-vyylaQEAY6w0vNXVKa3Ag3zVPD8=",
             "requires": {
                 "jquery": "^1.12.3"
             },
@@ -14918,7 +14951,7 @@
                 "jquery": {
                     "version": "1.12.4",
                     "resolved": "https://registry.npmjs.org/jquery/-/jquery-1.12.4.tgz",
-                    "integrity": "sha512-UEVp7PPK9xXYSk8xqXCJrkXnKZtlgWkd2GsAQbMRFK6S/ePU2JN5G2Zum8hIVjzR3CpdfSqdqAzId/xd4TJHeg=="
+                    "integrity": "sha1-AeHfuikP5z3rp3zurLD5ui/sngw="
                 }
             }
         },
@@ -15088,7 +15121,7 @@
         "media-typer": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
-            "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
+            "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
         },
         "memfs": {
             "version": "3.4.13",
@@ -15139,7 +15172,7 @@
         "memorystream": {
             "version": "0.3.1",
             "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
-            "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw=="
+            "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI="
         },
         "meow": {
             "version": "3.7.0",
@@ -15169,7 +15202,7 @@
         "merge-descriptors": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
-            "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
+            "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
         },
         "merge-stream": {
             "version": "2.0.0",
@@ -15180,7 +15213,7 @@
         "methods": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
-            "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="
+            "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
         },
         "microevent.ts": {
             "version": "0.1.1",
@@ -15744,7 +15777,7 @@
                 "he": {
                     "version": "1.1.1",
                     "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
-                    "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==",
+                    "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
                     "dev": true
                 },
                 "minimatch": {
@@ -15774,7 +15807,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
                     "dev": true
                 },
                 "supports-color": {
@@ -15959,14 +15992,14 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 }
             }
         },
         "mr-parser": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/mr-parser/-/mr-parser-0.2.1.tgz",
-            "integrity": "sha512-hug+mpbSSKnH13rFqy3zm+XiG+QTStiDAgMTHK355TIstQE0qBkBtSJsa5YHP94AuarVX9b/4dcebdTRZ9YiEw=="
+            "integrity": "sha1-hhi5ukF+KOn0OaQcaVtVTq/u2Sc="
         },
         "mri": {
             "version": "1.2.0",
@@ -16036,7 +16069,7 @@
         "native-or-bluebird": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/native-or-bluebird/-/native-or-bluebird-1.2.0.tgz",
-            "integrity": "sha512-0SH8UubxDfe382eYiwmd12qxAbiWGzlGZv6CkMA+DPojWa/Y0oH4hE0lRtFfFgJmPQFyKXeB8XxPbZz6TvvKaQ=="
+            "integrity": "sha1-OcR7/Xgl0fuf+tMiEK4l2q3xAck="
         },
         "natural-compare": {
             "version": "1.4.0",
@@ -16063,7 +16096,7 @@
         "nextafter": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/nextafter/-/nextafter-1.0.0.tgz",
-            "integrity": "sha512-7PO+A89Tll2rSEfyrjtqO0MaI37+nnxBdnQcPypfbEYYuGaJxWGCqaOwQX4a3GHNTS08l1kazuiLEWZniZjMUQ==",
+            "integrity": "sha1-t9d7U1MQ4+CX5gJauwqQNHfsGjo=",
             "requires": {
                 "double-bits": "^1.1.0"
             }
@@ -16094,7 +16127,7 @@
         "node-ensure": {
             "version": "0.0.0",
             "resolved": "https://registry.npmjs.org/node-ensure/-/node-ensure-0.0.0.tgz",
-            "integrity": "sha512-DRI60hzo2oKN1ma0ckc6nQWlHU69RH6xN0sjQTjMpChPfTYvKZdcQFfdYK2RWbJcKyUizSIy/l8OTGxMAM1QDw=="
+            "integrity": "sha1-7K52QVDemYYexcgQ/V0Jaxg5Mqc="
         },
         "node-environment-flags": {
             "version": "1.0.5",
@@ -20198,7 +20231,7 @@
         "oauth": {
             "version": "0.9.15",
             "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
-            "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
+            "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
         },
         "oauth-sign": {
             "version": "0.9.0",
@@ -20208,12 +20241,12 @@
         "object-assign": {
             "version": "4.1.1",
             "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-            "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
+            "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
         },
         "object-copy": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
-            "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
+            "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
             "requires": {
                 "copy-descriptor": "^0.1.0",
                 "define-property": "^0.2.5",
@@ -20223,7 +20256,7 @@
                 "define-property": {
                     "version": "0.2.5",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-                    "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+                    "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
                         "is-descriptor": "^0.1.0"
                     }
@@ -20236,7 +20269,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -20306,7 +20339,7 @@
         "object-visit": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
-            "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
+            "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
             "requires": {
                 "isobject": "^3.0.0"
             }
@@ -20368,7 +20401,7 @@
         "object.pick": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
-            "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+            "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
             "requires": {
                 "isobject": "^3.0.1"
             }
@@ -20406,7 +20439,7 @@
         "once": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-            "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+            "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
             "requires": {
                 "wrappy": "1"
             }
@@ -20507,7 +20540,7 @@
         "os-tmpdir": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-            "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="
+            "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
         },
         "osenv": {
             "version": "0.1.5",
@@ -20526,7 +20559,7 @@
         "p-debounce": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/p-debounce/-/p-debounce-1.0.0.tgz",
-            "integrity": "sha512-ttOxn4Yt0hzIsLLqKi/Ry9QRxW+UQKdoWHz7g99Ci57zPkqUU3kbWKAeHuv+HfRLe109acYLUY6kuVCOOqnt4g=="
+            "integrity": "sha1-y38svu/YegnrqGHhErZ1J+Yh4v0="
         },
         "p-finally": {
             "version": "1.0.0",
@@ -20703,7 +20736,7 @@
         "pascalcase": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
-            "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw=="
+            "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ="
         },
         "passport": {
             "version": "0.4.1",
@@ -20725,7 +20758,7 @@
         "passport-local": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
-            "integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
+            "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=",
             "requires": {
                 "passport-strategy": "1.x.x"
             }
@@ -20745,7 +20778,7 @@
         "passport-strategy": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
-            "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA=="
+            "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
         },
         "path-browserify": {
             "version": "1.0.1",
@@ -20760,12 +20793,12 @@
         "path-exists": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-            "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="
+            "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
         },
         "path-is-absolute": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+            "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
         "path-is-inside": {
             "version": "1.0.2",
@@ -20775,7 +20808,7 @@
         "path-key": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-            "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
+            "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
         },
         "path-parse": {
             "version": "1.0.7",
@@ -20785,7 +20818,7 @@
         "path-to-regexp": {
             "version": "0.1.7",
             "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
-            "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
+            "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
         },
         "path-type": {
             "version": "4.0.0",
@@ -20800,7 +20833,7 @@
         "pause": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
-            "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
+            "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
         },
         "pdf-parse": {
             "version": "1.1.1",
@@ -20848,7 +20881,7 @@
         "pend": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
-            "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
+            "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
         },
         "perfect-scrollbar": {
             "version": "1.5.5",
@@ -20858,7 +20891,7 @@
         "performance-now": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-            "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+            "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
         },
         "picocolors": {
             "version": "1.0.0",
@@ -21004,7 +21037,7 @@
         "posix-character-classes": {
             "version": "0.1.1",
             "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
-            "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg=="
+            "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
         },
         "postcss": {
             "version": "7.0.39",
@@ -21257,7 +21290,7 @@
         "process": {
             "version": "0.11.10",
             "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
-            "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
+            "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
         },
         "process-nextick-args": {
             "version": "2.0.1",
@@ -21331,7 +21364,7 @@
         "prosemirror-find-replace": {
             "version": "0.9.0",
             "resolved": "https://registry.npmjs.org/prosemirror-find-replace/-/prosemirror-find-replace-0.9.0.tgz",
-            "integrity": "sha512-LfhQ/Zr0PkkJpCsr9vTJ5ZPYh49mSVVG+hHJ6djT+chlCW+t2ilSxBpBG+2IeE/I5nlbcvuLLAbxeI1g3pTCpA=="
+            "integrity": "sha1-QgsENNF5xdBJD44hSNhVGpVJY4I="
         },
         "prosemirror-history": {
             "version": "1.3.0",
@@ -21436,7 +21469,7 @@
         "prr": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
-            "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
+            "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
             "dev": true
         },
         "pseudomap": {
@@ -21674,12 +21707,12 @@
         "pure-color": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/pure-color/-/pure-color-1.3.0.tgz",
-            "integrity": "sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA=="
+            "integrity": "sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4="
         },
         "q": {
             "version": "1.5.1",
             "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-            "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="
+            "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
         },
         "qs": {
             "version": "6.5.3",
@@ -21727,7 +21760,7 @@
         "random-bytes": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
-            "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ=="
+            "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
         },
         "randombytes": {
             "version": "2.1.0",
@@ -21830,7 +21863,7 @@
         "react-base16-styling": {
             "version": "0.5.3",
             "resolved": "https://registry.npmjs.org/react-base16-styling/-/react-base16-styling-0.5.3.tgz",
-            "integrity": "sha512-EPuchwVvYPSFFIjGpH0k6wM0HQsmJ0vCk7BSl5ryxMVFIWW4hX4Kksu4PNtxfgOxDebTLkJQ8iC7zwAql0eusg==",
+            "integrity": "sha1-OFjyTpxN2MvT9wLz901YHKKRcmk=",
             "requires": {
                 "base16": "^1.0.0",
                 "lodash.curry": "^4.0.1",
@@ -21904,7 +21937,7 @@
         "react-dock": {
             "version": "0.2.4",
             "resolved": "https://registry.npmjs.org/react-dock/-/react-dock-0.2.4.tgz",
-            "integrity": "sha512-ywUJPC/TIM9PO700skka0fH4aqbrH8RojUXejZFvjtqlc5KZ+xjHqFdo4A3j+dp+0NLFZ3Nai4xzcf3FUJ9BsQ==",
+            "integrity": "sha1-5yfcdVCztzEWY13LnA4E0Lev4Xw=",
             "requires": {
                 "lodash.debounce": "^3.1.1",
                 "prop-types": "^15.5.8"
@@ -22267,7 +22300,7 @@
         "react-themeable": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/react-themeable/-/react-themeable-1.1.0.tgz",
-            "integrity": "sha512-kl5tQ8K+r9IdQXZd8WLa+xxYN04lLnJXRVhHfdgwsUJr/SlKJxIejoc9z9obEkx1mdqbTw1ry43fxEUwyD9u7w==",
+            "integrity": "sha1-fURm3ZsrX6dQWHJ4JenxUro3mg4=",
             "requires": {
                 "object-assign": "^3.0.0"
             },
@@ -22275,7 +22308,7 @@
                 "object-assign": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
-                    "integrity": "sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ=="
+                    "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I="
                 }
             }
         },
@@ -22424,7 +22457,7 @@
         "readline": {
             "version": "1.3.0",
             "resolved": "https://registry.npmjs.org/readline/-/readline-1.3.0.tgz",
-            "integrity": "sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg=="
+            "integrity": "sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw="
         },
         "recharts": {
             "version": "2.5.0",
@@ -22453,7 +22486,7 @@
         "rechoir": {
             "version": "0.6.2",
             "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
-            "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
+            "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
             "requires": {
                 "resolve": "^1.1.6"
             }
@@ -22621,7 +22654,7 @@
         "relateurl": {
             "version": "0.2.7",
             "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
-            "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog=="
+            "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk="
         },
         "remark-gfm": {
             "version": "3.0.1",
@@ -22744,7 +22777,7 @@
         "repeat-string": {
             "version": "1.6.1",
             "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
-            "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="
+            "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
         },
         "repeating": {
             "version": "2.0.1",
@@ -22853,7 +22886,7 @@
         "require-directory": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-            "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+            "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
         },
         "require-from-string": {
             "version": "2.0.2",
@@ -22868,7 +22901,7 @@
         "require-package-name": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/require-package-name/-/require-package-name-2.0.1.tgz",
-            "integrity": "sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q=="
+            "integrity": "sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk="
         },
         "require_optional": {
             "version": "1.0.1",
@@ -22889,7 +22922,7 @@
         "requires-port": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
-            "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
+            "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
         },
         "resize-observer-polyfill": {
             "version": "1.5.1",
@@ -22934,7 +22967,7 @@
         "resolve-url": {
             "version": "0.2.1",
             "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-            "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg=="
+            "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo="
         },
         "responselike": {
             "version": "3.0.0",
@@ -23080,7 +23113,7 @@
         "safe-regex": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
-            "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+            "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
             "requires": {
                 "ret": "~0.1.10"
             }
@@ -23178,7 +23211,7 @@
         "scss-loader": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/scss-loader/-/scss-loader-0.0.1.tgz",
-            "integrity": "sha512-SbT/smRJjkvvdHSEdAYAplosVkrtaSwwgUlnQCOuDS5sOKNjrS/eYCMvKeV6+YxK5cCOCsOJZd3vltrXatFp+g==",
+            "integrity": "sha1-6uAXueDzjBKlMtslwiC5Avs05nE=",
             "dev": true
         },
         "scss-tokenizer": {
@@ -23208,17 +23241,17 @@
         "section-iterator": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/section-iterator/-/section-iterator-2.0.0.tgz",
-            "integrity": "sha512-xvTNwcbeDayXotnV32zLb3duQsP+4XosHpb/F+tu6VzEZFmIjzPdNk6/O+QOOx5XTh08KL2ufdXeCO33p380pQ=="
+            "integrity": "sha1-v0RNev7rlK1Dw5rS+yYVFifMuio="
         },
         "select": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
-            "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA=="
+            "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
         },
         "select-hose": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
-            "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==",
+            "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
             "dev": true
         },
         "selfsigned": {
@@ -23238,7 +23271,7 @@
         "semver-compare": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
-            "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow=="
+            "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w="
         },
         "semver-diff": {
             "version": "2.1.0",
@@ -23307,7 +23340,7 @@
         "serve-index": {
             "version": "1.9.1",
             "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
-            "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+            "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
             "dev": true,
             "requires": {
                 "accepts": "~1.3.4",
@@ -23337,7 +23370,7 @@
                 "http-errors": {
                     "version": "1.6.3",
                     "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
-                    "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+                    "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
                     "dev": true,
                     "requires": {
                         "depd": "~1.1.2",
@@ -23349,13 +23382,13 @@
                 "inherits": {
                     "version": "2.0.3",
                     "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-                    "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+                    "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
                     "dev": true
                 },
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
                     "dev": true
                 },
                 "setprototypeof": {
@@ -23367,7 +23400,7 @@
                 "statuses": {
                     "version": "1.5.0",
                     "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
-                    "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+                    "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
                     "dev": true
                 }
             }
@@ -23386,7 +23419,7 @@
         "set-blocking": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-            "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+            "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
         },
         "set-value": {
             "version": "2.0.1",
@@ -23402,7 +23435,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -23420,7 +23453,7 @@
         "setimmediate": {
             "version": "1.0.5",
             "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-            "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+            "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
         },
         "setprototypeof": {
             "version": "1.2.0",
@@ -23595,7 +23628,7 @@
         "shebang-command": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-            "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+            "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
             "requires": {
                 "shebang-regex": "^1.0.0"
             }
@@ -23603,7 +23636,7 @@
         "shebang-regex": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-            "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="
+            "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
         },
         "shelljs": {
             "version": "0.8.5",
@@ -23638,7 +23671,7 @@
         "simple-assign": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/simple-assign/-/simple-assign-0.1.0.tgz",
-            "integrity": "sha512-otdSSQzuVsmDoe5MnSm4ZgHd5sl0ak6A1CTjW1R/DUHQ8xoZuU1NUzf9x6n9Dvp3nxpvW51WNMQ/7rQ9432xDg=="
+            "integrity": "sha1-F/0wZqXz13OPUDIbsPFMooHMS6o="
         },
         "simple-concat": {
             "version": "1.0.1",
@@ -23658,7 +23691,7 @@
         "simple-swizzle": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
-            "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+            "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
             "requires": {
                 "is-arrayish": "^0.3.1"
             },
@@ -23690,7 +23723,7 @@
         "sliced": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
-            "integrity": "sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA=="
+            "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
         },
         "snapdragon": {
             "version": "0.8.2",
@@ -23718,7 +23751,7 @@
                 "define-property": {
                     "version": "0.2.5",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-                    "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+                    "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
                         "is-descriptor": "^0.1.0"
                     }
@@ -23726,7 +23759,7 @@
                 "extend-shallow": {
                     "version": "2.0.1",
                     "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
-                    "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+                    "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
                     "requires": {
                         "is-extendable": "^0.1.0"
                     }
@@ -23734,7 +23767,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 }
             }
         },
@@ -23751,7 +23784,7 @@
                 "define-property": {
                     "version": "1.0.0",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
-                    "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+                    "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
                     "requires": {
                         "is-descriptor": "^1.0.0"
                     }
@@ -23800,7 +23833,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -23969,7 +24002,7 @@
         "source-map": {
             "version": "0.5.7",
             "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-            "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="
+            "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
         },
         "source-map-js": {
             "version": "1.0.2",
@@ -24017,7 +24050,7 @@
         "sparse-bitfield": {
             "version": "3.0.3",
             "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
-            "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==",
+            "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
             "optional": true,
             "requires": {
                 "memory-pager": "^1.0.2"
@@ -24133,7 +24166,7 @@
         "sprintf-js": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-            "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
+            "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
         },
         "sshpk": {
             "version": "1.17.0",
@@ -24163,12 +24196,12 @@
         "standard-error": {
             "version": "1.1.0",
             "resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz",
-            "integrity": "sha512-4v7qzU7oLJfMI5EltUSHCaaOd65J6S4BqKRWgzMi4EYaE5fvNabPxmAPGdxpGXqrcWjhDGI/H09CIdEuUOUeXg=="
+            "integrity": "sha1-I+UWj6HAggGJ5YEnAaeQWFENDTQ="
         },
         "standard-http-error": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz",
-            "integrity": "sha512-DX/xPIoyXQTuY6BMZK4Utyi4l3A4vFoafsfqrU6/dO4Oe/59c7PyqPd2IQj9m+ZieDg2K3RL9xOYJsabcD9IUA==",
+            "integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=",
             "requires": {
                 "standard-error": ">= 1.1.0 < 2"
             }
@@ -24176,7 +24209,7 @@
         "static-extend": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
-            "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
+            "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
             "requires": {
                 "define-property": "^0.2.5",
                 "object-copy": "^0.1.0"
@@ -24185,7 +24218,7 @@
                 "define-property": {
                     "version": "0.2.5",
                     "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
-                    "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+                    "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
                     "requires": {
                         "is-descriptor": "^0.1.0"
                     }
@@ -24224,7 +24257,7 @@
         "stealthy-require": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
-            "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g=="
+            "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
         },
         "stop-iteration-iterator": {
             "version": "1.0.0",
@@ -24257,7 +24290,7 @@
         "stream-parser": {
             "version": "0.3.1",
             "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
-            "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==",
+            "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
             "requires": {
                 "debug": "2"
             },
@@ -24273,7 +24306,7 @@
                 "ms": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-                    "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+                    "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
                 }
             }
         },
@@ -24286,7 +24319,7 @@
         "strict-uri-encode": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
-            "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ=="
+            "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
         },
         "string-width": {
             "version": "2.1.1",
@@ -24376,7 +24409,7 @@
         "strip-ansi": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-            "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+            "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
             "requires": {
                 "ansi-regex": "^3.0.0"
             }
@@ -24412,7 +24445,7 @@
         "strip-json-comments": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-            "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="
+            "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
         },
         "style-loader": {
             "version": "0.23.1",
@@ -24614,7 +24647,7 @@
         "temp-dir": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
-            "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ=="
+            "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
         },
         "tempy": {
             "version": "0.2.1",
@@ -24696,7 +24729,7 @@
         "through": {
             "version": "2.3.8",
             "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-            "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
+            "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
         },
         "through2": {
             "version": "2.0.5",
@@ -24773,7 +24806,7 @@
         "to-array": {
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
-            "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A=="
+            "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
         },
         "to-fast-properties": {
             "version": "2.0.0",
@@ -24783,7 +24816,7 @@
         "to-object-path": {
             "version": "0.3.0",
             "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
-            "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
+            "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
             "requires": {
                 "kind-of": "^3.0.2"
             },
@@ -24796,7 +24829,7 @@
                 "kind-of": {
                     "version": "3.2.2",
                     "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
-                    "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+                    "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
                     "requires": {
                         "is-buffer": "^1.1.5"
                     }
@@ -24817,7 +24850,7 @@
         "to-regex-range": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
-            "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+            "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
             "requires": {
                 "is-number": "^3.0.0",
                 "repeat-string": "^1.6.1"
@@ -24844,7 +24877,7 @@
                 "nopt": {
                     "version": "1.0.10",
                     "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
-                    "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+                    "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
                     "requires": {
                         "abbrev": "1"
                     }
@@ -24865,7 +24898,7 @@
         "tr46": {
             "version": "0.0.3",
             "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-            "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+            "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
         },
         "translate-google-api": {
             "version": "1.0.4",
@@ -24893,7 +24926,7 @@
         "traverse-chain": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/traverse-chain/-/traverse-chain-0.1.0.tgz",
-            "integrity": "sha512-up6Yvai4PYKhpNp5PkYtx50m3KbwQrqDwbuZP/ItyL64YEWHAvH6Md83LFLV/GRSk/BoUVwwgUzX6SOQSbsfAg=="
+            "integrity": "sha1-YdvC1Ttp/2CRoSoWj9fUMxB+QPE="
         },
         "tree-kill": {
             "version": "1.2.2",
@@ -24927,7 +24960,7 @@
         "tryit": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
-            "integrity": "sha512-6C5h3CE+0qjGp+YKYTs74xR0k/Nw/ePtl/Lp6CCf44hqBQ66qnH1sDFR5mV/Gc48EsrHLB53lCFSffQCkka3kg=="
+            "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics="
         },
         "ts-loader": {
             "version": "5.4.5",
@@ -25271,7 +25304,7 @@
         "tunnel-agent": {
             "version": "0.6.0",
             "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+            "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
             "requires": {
                 "safe-buffer": "^5.0.1"
             }
@@ -25279,7 +25312,13 @@
         "tweetnacl": {
             "version": "0.14.5",
             "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-            "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+            "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+        },
+        "type": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
+            "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==",
+            "dev": true
         },
         "type-check": {
             "version": "0.4.0",
@@ -25328,7 +25367,7 @@
         "typedarray": {
             "version": "0.0.6",
             "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-            "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
+            "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
         },
         "typescript": {
             "version": "4.9.5",
@@ -25373,7 +25412,7 @@
                 "jsonfile": {
                     "version": "4.0.0",
                     "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-                    "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+                    "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
                     "requires": {
                         "graceful-fs": "^4.1.6"
                     }
@@ -25509,7 +25548,7 @@
         "unicode-trie": {
             "version": "0.3.1",
             "resolved": "https://registry.npmjs.org/unicode-trie/-/unicode-trie-0.3.1.tgz",
-            "integrity": "sha512-WgVuO0M2jDl7hVfbPgXv2LUrD81HM0bQj/bvLGiw6fJ4Zo8nNFnDrA0/hU2Te/wz6pjxCm5cxJwtLjo2eyV51Q==",
+            "integrity": "sha1-1nHd3YkQGgi6w3tqUWEBBgIFIIU=",
             "requires": {
                 "pako": "^0.2.5",
                 "tiny-inflate": "^1.0.0"
@@ -25518,7 +25557,7 @@
                 "pako": {
                     "version": "0.2.9",
                     "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
-                    "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="
+                    "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU="
                 }
             }
         },
@@ -25568,7 +25607,7 @@
         "unique-string": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
-            "integrity": "sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==",
+            "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
             "requires": {
                 "crypto-random-string": "^1.0.0"
             }
@@ -25641,12 +25680,12 @@
         "unpipe": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
-            "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
+            "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
         },
         "unset-value": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
-            "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
+            "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
             "requires": {
                 "has-value": "^0.3.1",
                 "isobject": "^3.0.0"
@@ -25655,7 +25694,7 @@
                 "has-value": {
                     "version": "0.3.1",
                     "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
-                    "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
+                    "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
                     "requires": {
                         "get-value": "^2.0.3",
                         "has-values": "^0.1.4",
@@ -25665,7 +25704,7 @@
                         "isobject": {
                             "version": "2.1.0",
                             "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
-                            "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
+                            "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
                             "requires": {
                                 "isarray": "1.0.0"
                             }
@@ -25675,7 +25714,7 @@
                 "has-values": {
                     "version": "0.1.4",
                     "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
-                    "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ=="
+                    "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E="
                 }
             }
         },
@@ -25741,7 +25780,7 @@
         "urix": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-            "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg=="
+            "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI="
         },
         "url": {
             "version": "0.11.0",
@@ -25833,12 +25872,12 @@
         "util-deprecate": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+            "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
         },
         "utila": {
             "version": "0.4.0",
             "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
-            "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA=="
+            "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw="
         },
         "utility-types": {
             "version": "3.10.0",
@@ -25848,7 +25887,7 @@
         "utils-merge": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
-            "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="
+            "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
         },
         "uuid": {
             "version": "3.4.0",
@@ -25858,7 +25897,7 @@
         "uuid-js": {
             "version": "0.7.5",
             "resolved": "https://registry.npmjs.org/uuid-js/-/uuid-js-0.7.5.tgz",
-            "integrity": "sha512-lJFducSMfVDO3E1wBe/zflgU25JbpX9KfF+g0k6OxIt9xeybdZd27n75vPg+4cLN55UKGjJ46w3K3q3l+8KgkQ=="
+            "integrity": "sha1-bIhtAqU9LUDc8l2RoXC0p7JblNA="
         },
         "uvu": {
             "version": "0.5.6",
@@ -25893,7 +25932,7 @@
         "valid-url": {
             "version": "1.0.9",
             "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
-            "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
+            "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA="
         },
         "validate-npm-package-license": {
             "version": "3.0.4",
@@ -25912,12 +25951,12 @@
         "vary": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
-            "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
+            "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
         },
         "verror": {
             "version": "1.10.0",
             "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-            "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+            "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
             "requires": {
                 "assert-plus": "^1.0.0",
                 "core-util-is": "1.0.2",
@@ -26089,7 +26128,7 @@
         "warning": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
-            "integrity": "sha512-jMBt6pUrKn5I+OGgtQ4YZLdhIeJmObddh6CsibPxyQ5yPZm1XExSyzC1LCNX7BzhxWgiHmizBWJTHJIjMjTQYQ==",
+            "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
             "requires": {
                 "loose-envify": "^1.0.0"
             }
@@ -26121,7 +26160,7 @@
         "web-request": {
             "version": "1.0.7",
             "resolved": "https://registry.npmjs.org/web-request/-/web-request-1.0.7.tgz",
-            "integrity": "sha512-mVySwo0f8FFw77ZCEEjZ93g7SqAvWREj15FefhJgPkkylu7b185N/u3Oa92sNpMdhjcErGB7oGpOkAAIvflSjw==",
+            "integrity": "sha1-twxCs81FV3noLbaIYlOySR8r1Wk=",
             "requires": {
                 "request": "^2.69.0"
             }
@@ -26134,7 +26173,7 @@
         "webidl-conversions": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-            "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+            "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
         },
         "webpack": {
             "version": "5.75.0",
@@ -26420,7 +26459,7 @@
                 "resolve-cwd": {
                     "version": "2.0.0",
                     "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
-                    "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+                    "integrity": "sha512-ccu8zQTrzVr954472aUVPLEcB3YpKSYR3cg/3lo1okzobPBM+1INXBbBZlDbnI/hbEocnf8j0QVo43hQKrbchg==",
                     "dev": true,
                     "requires": {
                         "resolve-from": "^3.0.0"
@@ -26429,7 +26468,7 @@
                 "resolve-from": {
                     "version": "3.0.0",
                     "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
-                    "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+                    "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==",
                     "dev": true
                 },
                 "semver": {
@@ -26611,7 +26650,7 @@
         "whatwg-url": {
             "version": "5.0.0",
             "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-            "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+            "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
             "requires": {
                 "tr46": "~0.0.3",
                 "webidl-conversions": "^3.0.0"
@@ -26620,7 +26659,7 @@
         "when": {
             "version": "3.7.8",
             "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz",
-            "integrity": "sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw=="
+            "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I="
         },
         "which": {
             "version": "1.3.1",
@@ -26657,7 +26696,7 @@
         "which-module": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
-            "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q=="
+            "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
         },
         "which-pm-runs": {
             "version": "1.1.0",
@@ -26806,7 +26845,7 @@
         "wrappy": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+            "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
         },
         "write": {
             "version": "1.0.3",
@@ -26877,7 +26916,7 @@
         "xoauth2": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/xoauth2/-/xoauth2-1.2.0.tgz",
-            "integrity": "sha512-hKuNbkj3q/ifCcfWnW6KURP+6ExSuLdLG007gasNhMEMKlLaejNkIA6eu5Ol1xPP0/kzTuA87XHDaAcUw5k73Q=="
+            "integrity": "sha1-8u76wRRyyXHqO8RuVU60sSMhRuU="
         },
         "xregexp": {
             "version": "4.4.1",
@@ -26972,7 +27011,7 @@
         "yauzl": {
             "version": "2.10.0",
             "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
-            "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+            "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
             "requires": {
                 "buffer-crc32": "~0.2.3",
                 "fd-slicer": "~1.1.0"
@@ -26981,7 +27020,7 @@
         "yeast": {
             "version": "0.1.2",
             "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
-            "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg=="
+            "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
         },
         "yn": {
             "version": "3.1.1",
diff --git a/package.json b/package.json
index e301268dd..c7c6bb4f0 100644
--- a/package.json
+++ b/package.json
@@ -177,7 +177,7 @@
         "body-parser": "^1.19.2",
         "bootstrap": "^4.6.1",
         "brotli": "^1.3.3",
-        "browndash-components": "0.0.76",
+        "browndash-components": "0.0.78",
         "browser-assert": "^1.2.1",
         "bson": "^4.6.1",
         "canvas": "^2.9.3",
diff --git a/src/Utils.ts b/src/Utils.ts
index 2e06b5631..e03632c8b 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -6,6 +6,7 @@ import { Socket } from 'socket.io';
 import { Colors } from './client/views/global/globalEnums';
 import { Message } from './server/Message';
 import Color = require('color');
+import { DocumentType } from './client/documents/DocumentTypes';
 
 export namespace Utils {
     export let CLICK_TIME = 300;
@@ -15,6 +16,21 @@ export namespace Utils {
         return Date.now() - downTime < Utils.CLICK_TIME && Math.abs(x - downX) < Utils.DRAG_THRESHOLD && Math.abs(y - downY) < Utils.DRAG_THRESHOLD;
     }
 
+    export function cleanDocumentType(type: DocumentType)  {
+        switch(type) {
+            case DocumentType.IMG:
+                return "Image"
+            case DocumentType.AUDIO:
+                return "Audio"
+            case DocumentType.COL:
+                return "Collection"
+            case DocumentType.RTF:
+                return "Text"
+            default: 
+                return type.charAt(0).toUpperCase() + type.slice(1)
+        }
+    }
+
     export function readUploadedFileAsText(inputFile: File) {
         const temporaryFileReader = new FileReader();
 
diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 05401e2cd..b11e694ff 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -12,6 +12,7 @@
     }
 
     .sharing-contents {
+        padding: 10px;
         display: flex;
         flex-direction: column;
 
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 8e5ae7bc0..33c9992d0 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -551,7 +551,12 @@ export class SharingManager extends React.Component<{}> {
         return (
             <div className="sharing-interface">
                 {GroupManager.Instance?.currentGroup ? <GroupMemberView group={GroupManager.Instance.currentGroup} onCloseButtonClick={action(() => (GroupManager.Instance.currentGroup = undefined))} /> : null}
-                <div className="sharing-contents">
+                <div className="sharing-contents"
+                    style={{
+                        background: StrCast(Doc.UserDoc().userBackgroundColor),
+                        color: StrCast(Doc.UserDoc().userColor)
+                    }}
+                >
                     <p className="share-title">
                         <div className="share-info" onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties/sharing-and-permissions/', '_blank')}>
                             <FontAwesomeIcon icon={'question-circle'} size={'sm'} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/properties/sharing-and-permissions/', '_blank')} />
@@ -652,6 +657,13 @@ export class SharingManager extends React.Component<{}> {
     }
 
     render() {
-        return <MainViewModal contents={this.sharingInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
+        return <MainViewModal 
+            contents={this.sharingInterface} 
+            isDisplayed={this.isOpen} 
+            interactive={true} 
+            dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} 
+            overlayDisplayedOpacity={this.overlayOpacity} 
+            closeOnExternalClick={this.close} 
+        />;
     }
 }
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index e574d68de..cf746bbb3 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -180,7 +180,7 @@ export class DashboardView extends React.Component {
                             fillWidth
                         />
                         <Button 
-                            text={'Shared Dashboards' + '(' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
+                            text={'Shared Dashboards' + ' (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
                             active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
                             color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'lightgreen' : color}
                             align={'flex-start'}
@@ -226,7 +226,7 @@ export class DashboardView extends React.Component {
                                                 e.stopPropagation();
                                                 this.onContextMenu(dashboard, e);
                                             }}>
-                                            <Button size={Size.SMALL} color={color} icon={<FontAwesomeIcon color={color} size="lg" icon="bars" />} />
+                                            <Button size={Size.SMALL} color={color} icon={<FontAwesomeIcon color={color} icon="bars" />} />
                                         </div>
                                     </div>
                                     <div className={`background`} style={{
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 3148d9ddd..b0f9d5a7e 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -301,32 +301,6 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             // </Tooltip>
         );
     }
-    @computed
-    get perspectiveButton() {
-        return !this.selectedDoc ? null : (
-            <Tooltip title={<div className="dash-tooltip">Choose view perspective</div>} placement="top">
-                <div>
-                    <div className="propertiesButtons-linkFlyout">
-                        <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={this.onPerspectiveFlyout}>
-                            <div className={'propertiesButtons-linkButton-empty'} onPointerDown={e => e.stopPropagation()}>
-                                <FontAwesomeIcon className="documentdecorations-icon" icon="mouse-pointer" size="lg" />
-                            </div>
-                        </Flyout>
-                    </div>
-                    <div className="propertiesButtons-title"> Perspective </div>
-                </div>
-            </Tooltip>
-        );
-    }
-
-    @undoBatch
-    handlePerspectiveChange = (e: any) => {
-        this.selectedDoc && (this.selectedDoc._type_collection = e.target.value);
-        SelectionManager.Views()
-            .filter(dv => dv.docView)
-            .map(dv => dv.docView!)
-            .forEach(docView => (docView.layoutDoc._type_collection = e.target.value));
-    };
 
     @undoBatch
     @action
@@ -406,26 +380,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             </div>
         );
     }
-    @computed
-    get onPerspectiveFlyout() {
-        const excludedViewTypes = [CollectionViewType.Invalid, CollectionViewType.Docking, CollectionViewType.Pile, CollectionViewType.StackedTimeline, CollectionViewType.Linear];
 
-        const makeLabel = (value: string, label: string) => (
-            <div className="radio" key={label}>
-                <label>
-                    <input type="radio" value={value} checked={(this.selectedDoc?._type_collection ?? 'invalid') === value} onChange={this.handlePerspectiveChange} />
-                    {label}
-                </label>
-            </div>
-        );
-        return (
-            <form>
-                {Object.values(CollectionViewType)
-                    .filter(type => !excludedViewTypes.includes(type))
-                    .map(type => makeLabel(type, type))}
-            </form>
-        );
-    }
 
     render() {
         const layoutField = this.selectedDoc?.[Doc.LayoutFieldKey(this.selectedDoc)];
@@ -466,7 +421,6 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 {toggle(this.snapButton, { display: !isCollection ? 'none' : '' })}
                 {toggle(this.clustersButton, { display: !isFreeForm ? 'none' : '' })}
                 {toggle(this.panButton, { display: !isFreeForm ? 'none' : '' })}
-                {toggle(this.perspectiveButton, { display: !isCollection || isNovice ? 'none' : '' })}
             </div>
         );
     }
diff --git a/src/client/views/PropertiesView.scss b/src/client/views/PropertiesView.scss
index b195afbd8..6dbc11d29 100644
--- a/src/client/views/PropertiesView.scss
+++ b/src/client/views/PropertiesView.scss
@@ -23,7 +23,7 @@
 
     .propertiesView-name,
     .propertiesView-type {
-        padding: 0px 10px;
+        padding: 5px 10px;
     }
 
 
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index a61a14536..ae6f6afe2 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -7,7 +7,7 @@ import { concat, intersection } from 'lodash';
 import { Lambda, action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import { ColorState, SketchPicker } from 'react-color';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
 import { Doc, Field, FieldResult, HierarchyMapping, NumListCast, Opt, ReverseHierarchyMap, StrListCast } from '../../fields/Doc';
 import { AclAdmin, DocAcl, DocData, Height, Width } from '../../fields/DocSymbols';
 import { Id } from '../../fields/FieldSymbols';
@@ -32,7 +32,7 @@ import { PropertiesDocBacklinksSelector } from './PropertiesDocBacklinksSelector
 import { PropertiesDocContextSelector } from './PropertiesDocContextSelector';
 import './PropertiesView.scss';
 import { DefaultStyleProvider } from './StyleProvider';
-import { Button, Colors, EditableText, NumberDropdown, Size, Slider, Type } from 'browndash-components';
+import { Button, Colors, EditableText, NumberDropdown, Size, Slider, Type, NumberInput } from 'browndash-components';
 import { PropertiesSection } from './PropertiesSection';
 import { DocumentView, OpenWhere, StyleProviderFunc } from './nodes/DocumentView';
 import { PresBox, PresEffect, PresEffectDirection } from './nodes/trails';
@@ -548,11 +548,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     }
 
     @computed get type() {
-        const type = StrCast(this.selectedDoc?.type);
+        const type = Utils.cleanDocumentType(StrCast(this.selectedDoc?.type) as DocumentType);
         return (
             <Button
                 formLabel={"Type"}
                 text={type}
+                type={Type.SEC}
                 color={this.color}
                 align='flex-start'
                 fillWidth
@@ -992,35 +993,68 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         );
     }
 
+    getNumber = (label: string, unit: string, min: number, max: number, number: number, setNumber: any) => {
+        return <div>
+            <NumberInput
+                formLabel={label}
+                formLabelPlacement={'left'}
+                type={Type.SEC}
+                unit={unit} 
+                fillWidth 
+                color={this.color}
+                number={number}
+                setNumber={setNumber}
+            />
+            <Slider 
+                multithumb={false}
+                color={this.color}
+                size={Size.XSMALL} 
+                min={min} 
+                max={max}
+                unit={unit} 
+                number={number}
+                setNumber={setNumber}
+                fillWidth
+            />
+        </div>
+    }
+
     @computed get transformEditor() {
         return (
             <div className="transform-editor">
                 {this.isInk ? this.controlPointsButton : null}
-                <Slider 
-                    formLabel={'Height'} 
-                    multithumb={false}
-                    color={this.color}
-                    size={Size.XSMALL} 
-                    min={0} 
-                    max={1000} 
-                    number={Number(this.shapeHgt)}
-                    setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height')}
-                    fillWidth
-                />
-                <Slider 
-                    formLabel={'Width'} 
-                    multithumb={false}
-                    color={this.color}
-                    size={Size.XSMALL} 
-                    min={0} 
-                    max={1000} 
-                    number={Number(this.shapeWid)}
-                    setNumber={undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width')}
-                    fillWidth
-                />
-
-                {this.hgtInput}
-                {this.XpsInput}
+                {this.getNumber(
+                    "Height",
+                    " px",
+                    0,
+                    1000,
+                    Number(this.shapeHgt),
+                    undoable((val: string) => !isNaN(Number(val)) && (this.shapeHgt = val), 'set height')
+                )}
+                {this.getNumber(
+                    "Width",
+                    " px",
+                    0,
+                    1000,
+                    Number(this.shapeWid),
+                    undoable((val: string) => !isNaN(Number(val)) && (this.shapeWid = val), 'set width')
+                )}
+                {this.getNumber(
+                    "X Coordinate",
+                    " px",
+                    -2000,
+                    2000,
+                    Number(this.shapeXps),
+                    undoable((val: string) => !isNaN(Number(val)) && (this.shapeXps = val), 'set x coord')
+                )}
+                {this.getNumber(
+                    "Y Coordinate",
+                    " px",
+                    -2000,
+                    2000,
+                    Number(this.shapeYps),
+                    undoable((val: string) => !isNaN(Number(val)) && (this.shapeYps = val), 'set y coord')
+                )}
             </div>
         );
     }
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index 28f1b8bd9..aaca7110e 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -25,7 +25,11 @@ export class UndoStack extends React.Component<UndoStackProps> {
                     placement={`top-start`}
                     type={Type.TERT}
                     popup={
-                    <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} style={{ background: UndoManager.batchCounter.get() ? 'yellow' : undefined }}>
+                    <div className="undoStack-commandsContainer" ref={r => r?.scroll({ behavior: 'auto', top: r?.scrollHeight + 20 })} 
+                        style={{ 
+                            background: UndoManager.batchCounter.get() ? 'yellow' : StrCast(Doc.UserDoc().userBackgroundColor),
+                            color: StrCast(Doc.UserDoc().userColor)
+                        }}>
                         {UndoManager.undoStackNames.map((name, i) => (
                             <div className="undoStack-resultContainer" key={i}>
                                 <div className="undoStack-commandString">{name.replace(/[^\.]*\./, '')}</div>
diff --git a/src/client/views/nodes/FontIconBox/FontIconBox.tsx b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
index 2958fa737..e98faf2a0 100644
--- a/src/client/views/nodes/FontIconBox/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox/FontIconBox.tsx
@@ -20,6 +20,7 @@ import { OpenWhere } from '../DocumentView';
 import { RichTextMenu } from '../formattedText/RichTextMenu';
 import './FontIconBox.scss';
 import { SelectedDocView } from '../../selectedDoc';
+import { Utils } from '../../../../Utils';
 
 export enum ButtonType {
     TextButton = 'textBtn',
@@ -214,9 +215,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
                         console.log("doc selected", selected.title);
                         dropdown = false;
                         if (selectedDocs.length > 1) {
-                            text = selectedDocs.length + " documents selected"
+                            text = selectedDocs.length + " selected"
                         } else {
-                            text = selected.type === DocumentType.RTF ? 'Text' : StrCast(selected.type);
+                            text = Utils.cleanDocumentType(StrCast(selected.type) as DocumentType);
                             icon = Doc.toIcon(selected);
                         }
                         return <Popup
diff --git a/src/client/views/pdf/AnchorMenu.tsx b/src/client/views/pdf/AnchorMenu.tsx
index 64ea4f52c..07b2afd91 100644
--- a/src/client/views/pdf/AnchorMenu.tsx
+++ b/src/client/views/pdf/AnchorMenu.tsx
@@ -15,7 +15,7 @@ import { GPTPopup, GPTPopupMode } from './GPTPopup/GPTPopup';
 import { LightboxView } from '../LightboxView';
 import { EditorView } from 'prosemirror-view';
 import './AnchorMenu.scss';
-import { ColorPicker, Group, IconButton, Popup, Size, Type } from 'browndash-components';
+import { ColorPicker, Group, IconButton, Popup, Size, Toggle, ToggleType, Type } from 'browndash-components';
 import { StrCast } from '../../../fields/Types';
 
 @observer
@@ -371,29 +371,33 @@ export class AnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                 </>
             ) : (
                 <>
-                    <Tooltip key="trash" title={<div className="dash-tooltip">Remove Link Anchor</div>}>
-                        <button className="antimodeMenu-button" style={{ display: this.Delete === returnFalse ? 'none' : undefined }} onPointerDown={this.Delete}>
-                            <FontAwesomeIcon icon="trash-alt" size="lg" />
-                        </button>
-                    </Tooltip>
-                    <Tooltip key="Pin" title={<div className="dash-tooltip">Pin to Presentation</div>}>
-                        <button className="antimodeMenu-button" style={{ display: this.PinToPres === returnFalse ? 'none' : undefined }} onPointerDown={this.PinToPres}>
-                            <FontAwesomeIcon icon="map-pin" size="lg" />
-                        </button>
-                    </Tooltip>
-                    <Tooltip key="trail" title={<div className="dash-tooltip">Show Linked Trail</div>}>
-                        <button className="antimodeMenu-button" style={{ display: this.ShowTargetTrail === returnFalse ? 'none' : undefined }} onPointerDown={this.ShowTargetTrail}>
-                            <FontAwesomeIcon icon="taxi" size="lg" />
-                        </button>
-                    </Tooltip>
-                    <Tooltip key="toggle" title={<div className="dash-tooltip">make target visibility toggle on click</div>}>
-                        <button
-                            className="antimodeMenu-button"
-                            style={{ display: this.IsTargetToggler === returnFalse ? 'none' : undefined, color: this.IsTargetToggler() ? 'black' : 'white', backgroundColor: this.IsTargetToggler() ? 'white' : 'black' }}
-                            onPointerDown={this.MakeTargetToggle}>
-                            <FontAwesomeIcon icon="thumbtack" size="lg" />
-                        </button>
-                    </Tooltip>
+                    {this.Delete !== returnFalse && <IconButton 
+                        tooltip={'Remove Link Anchor'}
+                        onPointerDown={this.Delete}
+                        icon={<FontAwesomeIcon icon="trash-alt" />}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />}
+                    {this.PinToPres !== returnFalse && <IconButton 
+                        tooltip={'Pin to Presentation'}
+                        onPointerDown={this.PinToPres}
+                        icon={<FontAwesomeIcon icon="map-pin" />}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />}
+                    {this.ShowTargetTrail !== returnFalse && <IconButton 
+                        tooltip={'Show Linked Trail'}
+                        onPointerDown={this.ShowTargetTrail}
+                        icon={<FontAwesomeIcon icon="taxi" />}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />}
+                    {this.IsTargetToggler !== returnFalse && <Toggle
+                        tooltip={'Make target visibility toggle on click'}
+                        type={Type.PRIM}
+                        toggleType={ToggleType.BUTTON}
+                        toggleStatus={this.IsTargetToggler()}
+                        onClick={this.MakeTargetToggle}
+                        icon={<FontAwesomeIcon icon="thumbtack" />}
+                        color={StrCast(Doc.UserDoc().userColor)}
+                    />}
                 </>
             );
 
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
index 1c9e124a2..955a4a174 100644
--- a/src/client/views/selectedDoc/SelectedDocView.tsx
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -40,7 +40,7 @@ export class SelectedDocView extends React.Component<SelectedDocViewProps> {
                         onClick: () => {DocumentManager.Instance.showDocument(doc, options, finished);}
                     }
                 })}
-                color={Colors.WHITE}
+                color={StrCast(Doc.UserDoc().userColor)}
             />
         </div>
     }
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index b9d5ed924..5c5547180 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -119,14 +119,6 @@ export class TopBar extends React.Component {
                         dashView?.showContextMenu(e.clientX + 20, e.clientY + 30);
                     }}
                 />
-                <Button
-                    text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'}
-                    onClick={() => {
-                        SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
-                    }}
-                    color={this.color}
-                    size={Size.SMALL}
-                />
                 {!Doc.noviceMode && (
                     <IconButton
                         tooltip="Work on a copy of the dashboard layout"
@@ -152,15 +144,14 @@ export class TopBar extends React.Component {
     @computed get topbarRight() {
         return (
             <div className="topbar-right">
-                {Doc.ActiveDashboard && <Button
-                    text={GetEffectiveAcl(Doc.GetProto(Doc.ActiveDashboard)) === AclAdmin ? 'Share' : 'View Original'}
+                <Button
+                    text={GetEffectiveAcl(Doc.ActiveDashboard) === AclAdmin ? 'Share' : 'View Original'}
                     type={Type.TERT}
                     color={this.variantColor}
                     onClick={() => {
                         SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                     }}
-                    size={Size.SMALL}
-                />}
+                />
                 <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
                 <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                 <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
-- 
cgit v1.2.3-70-g09d2


From 16a1b7de3ec26187b3a426eb037a5e4f4b9fcc55 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 18 Jul 2023 10:33:55 -0400
Subject: consolidated server stats with server heartbeat

---
 src/client/util/ServerStats.tsx     | 22 +++++++++++++++++-----
 src/client/views/GestureOverlay.tsx |  1 -
 src/client/views/topbar/TopBar.tsx  | 10 ++++------
 3 files changed, 21 insertions(+), 12 deletions(-)

(limited to 'src/client/views/topbar/TopBar.tsx')

diff --git a/src/client/util/ServerStats.tsx b/src/client/util/ServerStats.tsx
index f84ad8598..b6aa4d95a 100644
--- a/src/client/util/ServerStats.tsx
+++ b/src/client/util/ServerStats.tsx
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { MainViewModal } from '../views/MainViewModal';
 import './SharingManager.scss';
+import { PingManager } from './PingManager';
 
 @observer
 export class ServerStats extends React.Component<{}> {
@@ -39,11 +40,22 @@ export class ServerStats extends React.Component<{}> {
      */
     @computed get sharingInterface() {
         return (
-            <div>
-                <span>Active users:{this._stats?.socketMap.length}</span>
-                {this._stats?.socketMap.map((user: any) => (
-                    <p>{user.username}</p>
-                ))}
+            <div style={{
+                display: "flex",
+                height: 300,
+                width: 400,
+                background: "black",
+                opacity: 0.6}}>
+                    <div style={{width: 300,height: 100,margin: "auto",display: "flex",flexDirection: "column"}}>
+                        {PingManager.Instance.IsBeating ? 'The server connection is active' :
+                            'The server connection has been interrupted.NOTE: Any changes made will appear to persist but will be lost after a browser refreshes.'}
+                          
+                    <br/>
+                    <span>Active users:{this._stats?.socketMap.length}</span>
+                    {this._stats?.socketMap.map((user: any) => (
+                        <p>{user.username}</p>
+                    ))}  
+                </div>
             </div>
         );
     }
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 9d4ac6c96..35d6d73e4 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -30,7 +30,6 @@ import {
     SetActiveInkColor,
     SetActiveInkWidth,
 } from './InkingStroke';
-import { InkTranscription } from './InkTranscription';
 import TouchScrollableMenu, { TouchScrollableMenuItem } from './TouchScrollableMenu';
 import { Touchable } from './Touchable';
 import { checkInksToGroup } from './global/globalScripts';
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 5c5547180..130e47a41 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -1,7 +1,6 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Button, IconButton, FontSize, Size, Type, isDark } from 'browndash-components';
+import { Button, IconButton, Size, Type, isDark } from 'browndash-components';
 import { action, computed, observable, reaction } from 'mobx';
-import { Tooltip } from '@mui/material';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaBug, FaCamera, FaStamp } from 'react-icons/fa';
@@ -16,11 +15,11 @@ import { ServerStats } from '../../util/ServerStats';
 import { SettingsManager } from '../../util/SettingsManager';
 import { SharingManager } from '../../util/SharingManager';
 import { UndoManager } from '../../util/UndoManager';
-import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { ContextMenu } from '../ContextMenu';
 import { DashboardView } from '../DashboardView';
-import { Colors } from '../global/globalEnums';
 import { MainView } from '../MainView';
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import { Colors } from '../global/globalEnums';
 import './TopBar.scss';
 
 /**
@@ -152,13 +151,12 @@ export class TopBar extends React.Component {
                         SharingManager.Instance.open(undefined, Doc.ActiveDashboard);
                     }}
                 />
-                <IconButton tooltip={"Server ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={ServerStats.Instance.open} icon={<FaStamp />} />
                 <IconButton tooltip={"Issue Reporter ⌘I"} size={Size.SMALL} color={this.color} onClick={ReportManager.Instance.open} icon={<FaBug />} />
                 <IconButton tooltip={"Documentation ⌘D"} size={Size.SMALL} color={this.color} onClick={() => window.open('https://brown-dash.github.io/Dash-Documentation/', '_blank')} icon={<FontAwesomeIcon icon="question-circle" />} />
                 <IconButton tooltip={"Settings ⌘⇧S"} size={Size.SMALL} color={this.color} onClick={SettingsManager.Instance.open} icon={<FontAwesomeIcon icon="cog" />} />
                 <IconButton
                     size={Size.SMALL}
-                    onClick={PingManager.Instance.showAlert}
+                    onClick={ServerStats.Instance.open}
                     type={Type.TERT}
                     tooltip={'Server is ' + (PingManager.Instance.IsBeating ? '' : 'NOT ') + 'running'}
                     color={this.happyHeart ? Colors.LIGHT_BLUE : Colors.ERROR_RED}
-- 
cgit v1.2.3-70-g09d2

