From ddf35f6b406a2f2e8c27c2c65d15206eaa3ddbe6 Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sat, 16 Dec 2023 14:15:56 -0500
Subject: starting calendar feature

---
 src/client/util/CalendarManager.tsx | 229 ++++++++++++++++++++++++++++++++++++
 1 file changed, 229 insertions(+)
 create mode 100644 src/client/util/CalendarManager.tsx

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
new file mode 100644
index 000000000..39ba41652
--- /dev/null
+++ b/src/client/util/CalendarManager.tsx
@@ -0,0 +1,229 @@
+import * as React from 'react';
+import './CalendarManager.scss';
+import { observer } from "mobx-react";
+import { action, computed, observable, runInAction } from 'mobx';
+import { Doc } from '../../fields/Doc';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { DictationOverlay } from '../views/DictationOverlay';
+import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
+import { MainViewModal } from '../views/MainViewModal';
+import { TextField } from '@material-ui/core';
+import Select from 'react-select';
+import { SettingsManager } from './SettingsManager';
+import { StrCast } from '../../fields/Types';
+import { SelectionManager } from './SelectionManager';
+import { DocumentManager } from './DocumentManager';
+import { DocData } from '../../fields/DocSymbols';
+import { DateRange, Range, RangeKeyDict } from 'react-date-range';
+import { Button } from 'browndash-components';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
+import 'react-date-range/dist/styles.css';
+import 'react-date-range/dist/theme/default.css';
+
+type CreationType = 'new-calendar' | 'existing-calendar' | 'manage-calendars';
+
+@observer
+export class CalendarManager extends React.Component<{}> {
+    public static Instance: CalendarManager;
+    @observable private isOpen = false; 
+    @observable private targetDoc: Doc | undefined; // the target document
+    @observable private targetDocView: DocumentView | undefined; // the DocumentView of the target doc
+    @observable private dialogueBoxOpacity = 1; // for the modal
+    @observable private overlayOpacity = 0.4; // for the modal
+    
+    @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
+
+    @observable private creationType: CreationType = 'new-calendar';
+
+    @observable 
+    calendarName: string = "";
+
+    @action
+    setInterationType = (type: CreationType) => {
+        this.creationType = type;
+    }
+
+
+    public open = (target?: DocumentView, target_doc?: Doc) => {
+        console.log('hi');
+        runInAction(() => {
+            this.targetDoc = target_doc || target?.props.Document;
+            this.targetDocView = target;
+            DictationOverlay.Instance.hasActiveModal = true;
+            this.isOpen = this.targetDoc !== undefined;
+        })
+    };
+
+    public close = action(() => {
+        this.isOpen = false;
+        TaskCompletionBox.taskCompleted = false;
+        setTimeout(
+            action(() => {
+                DictationOverlay.Instance.hasActiveModal = false;
+                this.targetDoc = undefined;
+            }), 500
+        );
+        this.layoutDocAcls = false;
+    });
+
+    constructor(props: {}) {
+        super(props);
+        CalendarManager.Instance = this;
+    }
+
+    componentDidMount(): void {
+        
+    }
+
+    private focusOn = (contents: string) => {
+        const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
+        const docs = SelectionManager.Views().length > 1 ? SelectionManager.Views().map(docView => docView.props.Document) : [this.targetDoc];
+        return (
+            <span
+                className="focus-span"
+                title={title}
+                onClick={() => {
+                    if (this.targetDoc && this.targetDocView && docs.length === 1) {
+                        DocumentManager.Instance.showDocument(this.targetDoc, { willZoomCentered: true });
+                    }
+                }}
+                onPointerEnter={action(() => {
+                    if (docs.length) {
+                        docs.forEach(doc => doc && Doc.BrushDoc(doc));
+                        this.dialogueBoxOpacity = 0.1;
+                        this.overlayOpacity = 0.1;
+                    }
+                })}
+                onPointerLeave={action(() => {
+                    if (docs.length) {
+                        docs.forEach(doc => doc && Doc.UnBrushDoc(doc));
+                        this.dialogueBoxOpacity = 1;
+                        this.overlayOpacity = 0.4;
+                    }
+                })}>
+                {contents}
+            </span>
+        );
+    };
+
+    @observable
+    selectedDateRange: Range[] = [{
+        startDate: new Date(),
+        endDate: undefined,
+        key: 'selection'
+    }]
+
+    @action
+    setSelectedDateRange = (range: Range[]) => {
+        this.selectedDateRange = range;
+    }
+
+    @computed
+    get createButtonActive() {
+        if (this.calendarName.length === 0) return false // disabled if no calendar name
+        let startDate: Date | undefined;
+        let endDate: Date | undefined;
+        try {
+            startDate = this.selectedDateRange[0].startDate;
+            endDate = this.selectedDateRange[0].endDate;
+        } catch (e: any){
+            return false; // disabled 
+        }
+        if (!startDate || !endDate) return false; // disabled if any is undefined
+        return true;
+    }
+
+    @computed
+    get calendarInterface(){
+        let docs = SelectionManager.Views().length < 2 ? [this.targetDoc] : SelectionManager.Views().map(docView => docView.rootDoc);
+        const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData];
+
+        const currentDate = new Date();
+
+        return (
+            <div 
+                className='calendar-interface'
+                style= {{
+                    background: SettingsManager.userBackgroundColor,
+                    color: StrCast(Doc.UserDoc().userColor)
+                }}
+                >
+                <p className="selected-doc-title" style={{ color: SettingsManager.userColor }}>
+                    <b>{this.focusOn(docs.length < 2 ? StrCast(targetDoc?.title, 'this document') : '-multiple-')}</b>
+                </p>
+                <div className='creation-type-container'>
+                    <div 
+                        className={`calendar-creation ${this.creationType === 'new-calendar' ? 'calendar-creation-selected' : ''}`}
+                        onClick={(e) => this.setInterationType('new-calendar')}
+                        >
+                        Add to New Calendar
+                    </div>
+                    <div 
+                        className={`calendar-creation ${this.creationType === 'existing-calendar' ? 'calendar-creation-selected' : ''}`}
+                        onClick={(e) => this.setInterationType('existing-calendar')}
+                        >
+                        Add to Existing calendar
+                    </div>
+                </div>
+                <div className='choose-calendar-container'>
+                    {this.creationType === 'new-calendar' ? 
+                        <TextField
+                            fullWidth
+                            placeholder='Enter calendar name...'
+                            variant='filled'
+                            style={{
+                                backgroundColor: 'white',
+                                color: 'black',
+                                borderRadius: '5px'
+
+                            }}
+                            
+                        />
+                    :
+                        <Select
+                            className='existing-calendar-search'
+                            placeholder='Search for existing calendar...'
+                            isMulti
+                            isSearchable
+                        >
+                            
+                        </Select>
+                    }
+                </div>
+                <div className='date-range-picker-container'>
+                    <DateRange
+                        className='react-date-range'
+                        editableDateInputs={true}
+                        // ranges={[selectionRange]}
+                        onChange={item => this.setSelectedDateRange([item.selection])}
+                        ranges={this.selectedDateRange}
+                    // onChange={this.handleSelect}
+                    />
+                </div>
+                <div className='create-button-container'>
+                    <Button
+                        active={this.createButtonActive}
+                        text="Add to Calendar"
+                        iconPlacement='right'
+                        icon={<FontAwesomeIcon icon={faPlus as IconLookup}/>}
+                    />
+                </div>
+                
+            </div>
+        )
+    }
+
+    render() {
+        return (
+        <MainViewModal 
+            contents={this.calendarInterface} 
+            isDisplayed={this.isOpen} 
+            interactive={true}
+            dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity}
+            overlayDisplayedOpacity={this.overlayOpacity}
+            closeOnExternalClick={this.close}
+        />
+        )
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 4a1d64e470f7f8fae90e5014f3e6e64c5ffea2c8 Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sat, 16 Dec 2023 17:26:32 -0500
Subject: more functionality for calendar feature

---
 package-lock.json                                  | 3025 +++++++++++++++++---
 package.json                                       |   10 +-
 src/client/documents/DocumentTypes.ts              |    2 +
 src/client/documents/Documents.ts                  |   11 +
 src/client/util/CalendarManager.tsx                |  153 +-
 src/client/views/DashboardView.tsx                 |   31 +-
 .../views/collections/CollectionDockingView.tsx    |    1 +
 src/fields/Doc.ts                                  |    1 +
 8 files changed, 2790 insertions(+), 444 deletions(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/package-lock.json b/package-lock.json
index 9dec742fb..29ab1ff66 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4,6 +4,78 @@
     "lockfileVersion": 1,
     "requires": true,
     "dependencies": {
+        "@adobe/react-spectrum": {
+            "version": "3.32.2",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum/-/react-spectrum-3.32.2.tgz",
+            "integrity": "sha512-dKDJquOlpATCe09Tf+hWwPRCFZOtIFQB0Sj79lf4ypUHONuHZCTzBz287OmnzflbvlRD8igUVru76e+xORD+YQ==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/ssr": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-spectrum/actionbar": "^3.4.0",
+                "@react-spectrum/actiongroup": "^3.10.0",
+                "@react-spectrum/avatar": "^3.0.7",
+                "@react-spectrum/badge": "^3.1.8",
+                "@react-spectrum/breadcrumbs": "^3.9.2",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/buttongroup": "^3.6.8",
+                "@react-spectrum/calendar": "^3.4.3",
+                "@react-spectrum/checkbox": "^3.9.0",
+                "@react-spectrum/combobox": "^3.11.2",
+                "@react-spectrum/contextualhelp": "^3.6.5",
+                "@react-spectrum/datepicker": "^3.9.0",
+                "@react-spectrum/dialog": "^3.8.5",
+                "@react-spectrum/divider": "^3.5.8",
+                "@react-spectrum/dnd": "^3.3.5",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/icon": "^3.7.8",
+                "@react-spectrum/illustratedmessage": "^3.4.8",
+                "@react-spectrum/image": "^3.4.8",
+                "@react-spectrum/inlinealert": "^3.2.0",
+                "@react-spectrum/labeledvalue": "^3.1.8",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/link": "^3.6.2",
+                "@react-spectrum/list": "^3.7.4",
+                "@react-spectrum/listbox": "^3.12.4",
+                "@react-spectrum/menu": "^3.16.0",
+                "@react-spectrum/meter": "^3.4.8",
+                "@react-spectrum/numberfield": "^3.8.0",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/picker": "^3.13.2",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/provider": "^3.9.2",
+                "@react-spectrum/radio": "^3.7.0",
+                "@react-spectrum/searchfield": "^3.8.0",
+                "@react-spectrum/slider": "^3.6.4",
+                "@react-spectrum/statuslight": "^3.5.8",
+                "@react-spectrum/switch": "^3.5.0",
+                "@react-spectrum/table": "^3.12.4",
+                "@react-spectrum/tabs": "^3.8.4",
+                "@react-spectrum/tag": "^3.2.0",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/textfield": "^3.11.0",
+                "@react-spectrum/theme-dark": "^3.5.7",
+                "@react-spectrum/theme-default": "^3.5.7",
+                "@react-spectrum/theme-light": "^3.4.7",
+                "@react-spectrum/tooltip": "^3.6.2",
+                "@react-spectrum/view": "^3.6.5",
+                "@react-spectrum/well": "^3.4.8",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/data": "^3.11.0",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@adobe/react-spectrum-ui": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-ui/-/react-spectrum-ui-1.2.0.tgz",
+            "integrity": "sha512-os3EdjfyJbrukLcZ5uYtdFRiDlLB3zq2JoXp19J/IDpZ8btibJeRZYSwjL+LscEiT2pOYaF2McMQdkZTIwnllw=="
+        },
+        "@adobe/react-spectrum-workflow": {
+            "version": "2.3.4",
+            "resolved": "https://registry.npmjs.org/@adobe/react-spectrum-workflow/-/react-spectrum-workflow-2.3.4.tgz",
+            "integrity": "sha512-XPLzIBl58HdLF9WIPB7RDAvVXvCE3SjG+HaWQhW2P9MnxSz1DEA9O7mlTlYblJkMbfk10T/+RFaSupc1yoN+TA=="
+        },
         "@ampproject/remapping": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
@@ -2879,6 +2951,50 @@
             "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.2.tgz",
             "integrity": "sha512-ou3elfqG/hZsbmF4bxeJhPHIf3G2pm0ujc39hYEZrfVqt7Vk/Zji6CXc3W0pmYM8BW1g40U+akTl9DKZhFhInQ=="
         },
+        "@formatjs/ecma402-abstract": {
+            "version": "1.18.0",
+            "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.0.tgz",
+            "integrity": "sha512-PEVLoa3zBevWSCZzPIM/lvPCi8P5l4G+NXQMc/CjEiaCWgyHieUoo0nM7Bs0n/NbuQ6JpXEolivQ9pKSBHaDlA==",
+            "requires": {
+                "@formatjs/intl-localematcher": "0.5.2",
+                "tslib": "^2.4.0"
+            }
+        },
+        "@formatjs/fast-memoize": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
+            "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
+            "requires": {
+                "tslib": "^2.4.0"
+            }
+        },
+        "@formatjs/icu-messageformat-parser": {
+            "version": "2.7.3",
+            "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.3.tgz",
+            "integrity": "sha512-X/jy10V9S/vW+qlplqhMUxR8wErQ0mmIYSq4mrjpjDl9mbuGcCILcI1SUYkL5nlM4PJqpc0KOS0bFkkJNPxYRw==",
+            "requires": {
+                "@formatjs/ecma402-abstract": "1.18.0",
+                "@formatjs/icu-skeleton-parser": "1.7.0",
+                "tslib": "^2.4.0"
+            }
+        },
+        "@formatjs/icu-skeleton-parser": {
+            "version": "1.7.0",
+            "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.7.0.tgz",
+            "integrity": "sha512-Cfdo/fgbZzpN/jlN/ptQVe0lRHora+8ezrEeg2RfrNjyp+YStwBy7cqDY8k5/z2LzXg6O0AdzAV91XS0zIWv+A==",
+            "requires": {
+                "@formatjs/ecma402-abstract": "1.18.0",
+                "tslib": "^2.4.0"
+            }
+        },
+        "@formatjs/intl-localematcher": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz",
+            "integrity": "sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw==",
+            "requires": {
+                "tslib": "^2.4.0"
+            }
+        },
         "@fortawesome/fontawesome-common-types": {
             "version": "6.4.0",
             "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz",
@@ -3036,30 +3152,44 @@
             "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
             "dev": true
         },
-        "@hypnosphi/create-react-context": {
-            "version": "0.3.1",
-            "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz",
-            "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==",
-            "requires": {
-                "gud": "^1.0.0",
-                "warning": "^4.0.3"
-            },
-            "dependencies": {
-                "warning": {
-                    "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
-                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
-                    "requires": {
-                        "loose-envify": "^1.0.0"
-                    }
-                }
-            }
-        },
         "@icons/material": {
             "version": "0.2.4",
             "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
             "integrity": "sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw=="
         },
+        "@internationalized/date": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.0.tgz",
+            "integrity": "sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@internationalized/message": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.1.tgz",
+            "integrity": "sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==",
+            "requires": {
+                "@swc/helpers": "^0.5.0",
+                "intl-messageformat": "^10.1.0"
+            }
+        },
+        "@internationalized/number": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.4.0.tgz",
+            "integrity": "sha512-8TvotW3qVDHC4uv/BVoN6Qx0Dm8clHY1/vpH+dh+XRiPW/9NVpKn1P8d1A+WLphWrMwyqyWXI7uWehJPviaeIw==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@internationalized/string": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.1.1.tgz",
+            "integrity": "sha512-fvSr6YRoVPgONiVIUhgCmIAlifMVCeej/snPZVzbzRPxGpHl3o1GRe+d/qh92D8KhgOciruDUH8I5mjdfdjzfA==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
         "@isaacs/cliui": {
             "version": "8.0.2",
             "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -3166,6 +3296,11 @@
                 "@jridgewell/sourcemap-codec": "1.4.14"
             }
         },
+        "@juggle/resize-observer": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
+            "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
+        },
         "@log4js-node/log4js-api": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
@@ -3992,234 +4127,6 @@
                 }
             }
         },
-        "@mui/x-date-pickers": {
-            "version": "6.18.5",
-            "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.18.5.tgz",
-            "integrity": "sha512-3jImYIWP2Xgi608yzm/Sz1v0MTjQQYdZSQOEIi3dWBfSAU9B06KXDpqlXfRSpTV+rtsnfYIIyiWlz6Ltk7sUWw==",
-            "requires": {
-                "@babel/runtime": "^7.23.2",
-                "@mui/base": "^5.0.0-beta.22",
-                "@mui/utils": "^5.14.16",
-                "@types/react-transition-group": "^4.4.8",
-                "clsx": "^2.0.0",
-                "prop-types": "^15.8.1",
-                "react-transition-group": "^4.4.5"
-            },
-            "dependencies": {
-                "@babel/runtime": {
-                    "version": "7.23.6",
-                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
-                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
-                    "requires": {
-                        "regenerator-runtime": "^0.14.0"
-                    }
-                },
-                "@floating-ui/react-dom": {
-                    "version": "2.0.4",
-                    "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz",
-                    "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==",
-                    "requires": {
-                        "@floating-ui/dom": "^1.5.1"
-                    }
-                },
-                "@mui/base": {
-                    "version": "5.0.0-beta.27",
-                    "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.27.tgz",
-                    "integrity": "sha512-duL37qxihT1N0pW/gyXVezP7SttLkF+cLAs/y6g6ubEFmVadjbnZ45SeF12/vAiKzqwf5M0uFH1cczIPXFZygA==",
-                    "requires": {
-                        "@babel/runtime": "^7.23.5",
-                        "@floating-ui/react-dom": "^2.0.4",
-                        "@mui/types": "^7.2.11",
-                        "@mui/utils": "^5.15.0",
-                        "@popperjs/core": "^2.11.8",
-                        "clsx": "^2.0.0",
-                        "prop-types": "^15.8.1"
-                    }
-                },
-                "@mui/types": {
-                    "version": "7.2.11",
-                    "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.11.tgz",
-                    "integrity": "sha512-KWe/QTEsFFlFSH+qRYf3zoFEj3z67s+qAuSnMMg+gFwbxG7P96Hm6g300inQL1Wy///gSRb8juX7Wafvp93m3w=="
-                },
-                "@mui/utils": {
-                    "version": "5.15.0",
-                    "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.0.tgz",
-                    "integrity": "sha512-XSmTKStpKYamewxyJ256+srwEnsT3/6eNo6G7+WC1tj2Iq9GfUJ/6yUoB7YXjOD2jTZ3XobToZm4pVz1LBt6GA==",
-                    "requires": {
-                        "@babel/runtime": "^7.23.5",
-                        "@types/prop-types": "^15.7.11",
-                        "prop-types": "^15.8.1",
-                        "react-is": "^18.2.0"
-                    }
-                },
-                "@popperjs/core": {
-                    "version": "2.11.8",
-                    "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
-                    "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
-                },
-                "@types/prop-types": {
-                    "version": "15.7.11",
-                    "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
-                    "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
-                },
-                "@types/react-transition-group": {
-                    "version": "4.4.10",
-                    "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz",
-                    "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==",
-                    "requires": {
-                        "@types/react": "*"
-                    }
-                },
-                "clsx": {
-                    "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
-                    "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="
-                },
-                "react-is": {
-                    "version": "18.2.0",
-                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
-                    "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
-                },
-                "regenerator-runtime": {
-                    "version": "0.14.1",
-                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
-                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
-                }
-            }
-        },
-        "@mui/x-date-pickers-pro": {
-            "version": "6.18.5",
-            "resolved": "https://registry.npmjs.org/@mui/x-date-pickers-pro/-/x-date-pickers-pro-6.18.5.tgz",
-            "integrity": "sha512-f1JKEpi0cVmsOTab3rnx1W4aEPuKnF9IU3Ib7an75rW321QdwFYTm9+V4ZwWnN0jwDq8+13jjhdDEzfqcX76RA==",
-            "requires": {
-                "@babel/runtime": "^7.23.2",
-                "@mui/base": "^5.0.0-beta.22",
-                "@mui/utils": "^5.14.16",
-                "@mui/x-date-pickers": "6.18.5",
-                "@mui/x-license-pro": "6.10.2",
-                "clsx": "^2.0.0",
-                "prop-types": "^15.8.1",
-                "react-transition-group": "^4.4.5"
-            },
-            "dependencies": {
-                "@babel/runtime": {
-                    "version": "7.23.6",
-                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
-                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
-                    "requires": {
-                        "regenerator-runtime": "^0.14.0"
-                    }
-                },
-                "@floating-ui/react-dom": {
-                    "version": "2.0.4",
-                    "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz",
-                    "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==",
-                    "requires": {
-                        "@floating-ui/dom": "^1.5.1"
-                    }
-                },
-                "@mui/base": {
-                    "version": "5.0.0-beta.27",
-                    "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.27.tgz",
-                    "integrity": "sha512-duL37qxihT1N0pW/gyXVezP7SttLkF+cLAs/y6g6ubEFmVadjbnZ45SeF12/vAiKzqwf5M0uFH1cczIPXFZygA==",
-                    "requires": {
-                        "@babel/runtime": "^7.23.5",
-                        "@floating-ui/react-dom": "^2.0.4",
-                        "@mui/types": "^7.2.11",
-                        "@mui/utils": "^5.15.0",
-                        "@popperjs/core": "^2.11.8",
-                        "clsx": "^2.0.0",
-                        "prop-types": "^15.8.1"
-                    }
-                },
-                "@mui/types": {
-                    "version": "7.2.11",
-                    "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.11.tgz",
-                    "integrity": "sha512-KWe/QTEsFFlFSH+qRYf3zoFEj3z67s+qAuSnMMg+gFwbxG7P96Hm6g300inQL1Wy///gSRb8juX7Wafvp93m3w=="
-                },
-                "@mui/utils": {
-                    "version": "5.15.0",
-                    "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.0.tgz",
-                    "integrity": "sha512-XSmTKStpKYamewxyJ256+srwEnsT3/6eNo6G7+WC1tj2Iq9GfUJ/6yUoB7YXjOD2jTZ3XobToZm4pVz1LBt6GA==",
-                    "requires": {
-                        "@babel/runtime": "^7.23.5",
-                        "@types/prop-types": "^15.7.11",
-                        "prop-types": "^15.8.1",
-                        "react-is": "^18.2.0"
-                    }
-                },
-                "@popperjs/core": {
-                    "version": "2.11.8",
-                    "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
-                    "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
-                },
-                "@types/prop-types": {
-                    "version": "15.7.11",
-                    "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
-                    "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
-                },
-                "clsx": {
-                    "version": "2.0.0",
-                    "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
-                    "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q=="
-                },
-                "react-is": {
-                    "version": "18.2.0",
-                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
-                    "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
-                },
-                "regenerator-runtime": {
-                    "version": "0.14.1",
-                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
-                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
-                }
-            }
-        },
-        "@mui/x-license-pro": {
-            "version": "6.10.2",
-            "resolved": "https://registry.npmjs.org/@mui/x-license-pro/-/x-license-pro-6.10.2.tgz",
-            "integrity": "sha512-Baw3shilU+eHgU+QYKNPFUKvfS5rSyNJ98pQx02E0gKA22hWp/XAt88K1qUfUMPlkPpvg/uci6gviQSSLZkuKw==",
-            "requires": {
-                "@babel/runtime": "^7.22.6",
-                "@mui/utils": "^5.13.7"
-            },
-            "dependencies": {
-                "@babel/runtime": {
-                    "version": "7.23.6",
-                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
-                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
-                    "requires": {
-                        "regenerator-runtime": "^0.14.0"
-                    }
-                },
-                "@mui/utils": {
-                    "version": "5.15.0",
-                    "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.0.tgz",
-                    "integrity": "sha512-XSmTKStpKYamewxyJ256+srwEnsT3/6eNo6G7+WC1tj2Iq9GfUJ/6yUoB7YXjOD2jTZ3XobToZm4pVz1LBt6GA==",
-                    "requires": {
-                        "@babel/runtime": "^7.23.5",
-                        "@types/prop-types": "^15.7.11",
-                        "prop-types": "^15.8.1",
-                        "react-is": "^18.2.0"
-                    }
-                },
-                "@types/prop-types": {
-                    "version": "15.7.11",
-                    "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
-                    "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="
-                },
-                "react-is": {
-                    "version": "18.2.0",
-                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
-                    "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
-                },
-                "regenerator-runtime": {
-                    "version": "0.14.1",
-                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
-                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
-                }
-            }
-        },
         "@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",
@@ -5320,138 +5227,2299 @@
                 }
             }
         },
-        "@octokit/auth-token": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
-            "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
+        "@octokit/auth-token": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.3.tgz",
+            "integrity": "sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA==",
+            "requires": {
+                "@octokit/types": "^9.0.0"
+            }
+        },
+        "@octokit/core": {
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
+            "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
+            "requires": {
+                "@octokit/auth-token": "^3.0.0",
+                "@octokit/graphql": "^5.0.0",
+                "@octokit/request": "^6.0.0",
+                "@octokit/request-error": "^3.0.0",
+                "@octokit/types": "^9.0.0",
+                "before-after-hook": "^2.2.0",
+                "universal-user-agent": "^6.0.0"
+            }
+        },
+        "@octokit/endpoint": {
+            "version": "7.0.5",
+            "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz",
+            "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==",
+            "requires": {
+                "@octokit/types": "^9.0.0",
+                "is-plain-object": "^5.0.0",
+                "universal-user-agent": "^6.0.0"
+            }
+        },
+        "@octokit/graphql": {
+            "version": "5.0.5",
+            "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
+            "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
+            "requires": {
+                "@octokit/request": "^6.0.0",
+                "@octokit/types": "^9.0.0",
+                "universal-user-agent": "^6.0.0"
+            }
+        },
+        "@octokit/openapi-types": {
+            "version": "16.0.0",
+            "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
+            "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
+        },
+        "@octokit/request": {
+            "version": "6.2.3",
+            "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz",
+            "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==",
+            "requires": {
+                "@octokit/endpoint": "^7.0.0",
+                "@octokit/request-error": "^3.0.0",
+                "@octokit/types": "^9.0.0",
+                "is-plain-object": "^5.0.0",
+                "node-fetch": "^2.6.7",
+                "universal-user-agent": "^6.0.0"
+            }
+        },
+        "@octokit/request-error": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
+            "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
+            "requires": {
+                "@octokit/types": "^9.0.0",
+                "deprecation": "^2.0.0",
+                "once": "^1.4.0"
+            }
+        },
+        "@octokit/types": {
+            "version": "9.0.0",
+            "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
+            "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
+            "requires": {
+                "@octokit/openapi-types": "^16.0.0"
+            }
+        },
+        "@opentelemetry/api": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
+            "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA=="
+        },
+        "@pkgjs/parseargs": {
+            "version": "0.11.0",
+            "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+            "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+            "optional": true
+        },
+        "@popperjs/core": {
+            "version": "2.11.7",
+            "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
+            "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
+        },
+        "@react-aria/actiongroup": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/actiongroup/-/actiongroup-3.7.0.tgz",
+            "integrity": "sha512-PAOoZbmvcEDy7qpYSXK+lxs7Jl0/7LpRQ+wze2muhsn8bHdPKl67lbUx8qY2L7fcamXNl4sCx/5w/MiS33HbDA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/actiongroup": "^3.4.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/breadcrumbs": {
+            "version": "3.5.8",
+            "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.8.tgz",
+            "integrity": "sha512-jeek23igeqXct7S3ShW2jtFUc5g3fS9ZEBZkF64FWBrwfCiaZwb8TcKkK/xFw36/q5mxEt+seNiqnNzvsICJuQ==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/link": "^3.6.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/breadcrumbs": "^3.7.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/button": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.9.0.tgz",
+            "integrity": "sha512-Jri4OCN+4YmpJDPNQvk1DJoskKD9sdTxZaWWWJdAwoSIunZk3IEBXVvRfKzsEAVtI+UJN25zC2kyjXbVPS2XAA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/calendar": {
+            "version": "3.5.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.5.3.tgz",
+            "integrity": "sha512-jW48jk0TIe0HAJS+z8zqd8M86FEuqrk1qEIjMWnf8rFnA7hPPpjdjUrY9vSIeC95NcbyZbFnr1bHzQjAIzosQw==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/calendar": "^3.4.2",
+                "@react-types/button": "^3.9.1",
+                "@react-types/calendar": "^3.4.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/checkbox": {
+            "version": "3.12.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.12.0.tgz",
+            "integrity": "sha512-CyFZoI+z9hhyB3wb7IBsZxE30vXfYO2vSyET16zlkJ4qiFMqMiVLE4ekq034MHltCdpAczgP5yfKgNnJOmj7vQ==",
+            "requires": {
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/toggle": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/checkbox": "^3.6.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/checkbox": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/combobox": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.8.0.tgz",
+            "integrity": "sha512-lInzzZrH4vFlxmvDpXgQRkkREm7YIx258IRpQqll8Bny2vKMmZoF06zWMbcHP0CjFqYxExQeTjSYx0OTRRxkCQ==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/listbox": "^3.11.2",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/menu": "^3.11.2",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/textfield": "^3.13.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/combobox": "^3.8.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/combobox": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/datepicker": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.9.0.tgz",
+            "integrity": "sha512-FIpiJxwBNOM8a6hLOqQJ4JrvRiGL6Zr44E1mHtAWStp2kBEJ6+O2JRm4PQ5Pzvdw6xnCpOBdfESdNdlXN7lVqQ==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@internationalized/number": "^3.4.0",
+                "@internationalized/string": "^3.1.1",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/spinbutton": "^3.6.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/datepicker": "^3.9.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/calendar": "^3.4.2",
+                "@react-types/datepicker": "^3.7.0",
+                "@react-types/dialog": "^3.5.7",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/dialog": {
+            "version": "3.5.8",
+            "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.8.tgz",
+            "integrity": "sha512-KIc1FORdHhZ3bWom4qHO0hmlL4e5Hup6N25EY8HP5I7Ftv9EBBGaO5grtxZ2fX8kiCJNI4y+k67ZZ71wKJvMiA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/dialog": "^3.5.7",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/dnd": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.5.0.tgz",
+            "integrity": "sha512-6IuqmXwnfgRfeXDbfsPZzScapCmtRIkphTBPoLT575uEbZC7ROLgRJ/4NIKxvtTA6IIBqUGcvaqU9Mpg8j4U5Q==",
+            "requires": {
+                "@internationalized/string": "^3.1.1",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/dnd": "^3.2.6",
+                "@react-types/button": "^3.9.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/focus": {
+            "version": "3.15.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.15.0.tgz",
+            "integrity": "sha512-nnxRyfqHuAjRwdQ4BpQyZPtGFKZmRU6cnaIb3pqWFCqEyJQensV7MA3TJ4Jhadq67cy1Ji5SYSlr1duBwjoYvw==",
+            "requires": {
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0",
+                "clsx": "^1.1.1"
+            }
+        },
+        "@react-aria/form": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.0.tgz",
+            "integrity": "sha512-APeGph9oTO8nro4ZObuy1hk+0hpF/ji9O3odPGhLkzP/HvW2J7NI9pjKJOINfgtYr2yvVUZf/MbTMxPwtAxhaQ==",
+            "requires": {
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/grid": {
+            "version": "3.8.5",
+            "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.8.5.tgz",
+            "integrity": "sha512-0p+Bbs9rpQeOy8b75DamlzVPKylBoe/z0XwkeeTChHP2TK3TwPXh6J5EmisQx6K8zsb3iZULQRcP4QibvnMbrg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/grid": "^3.8.3",
+                "@react-stately/selection": "^3.14.1",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/checkbox": "^3.6.0",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/gridlist": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.7.2.tgz",
+            "integrity": "sha512-9keGYZz0yILVqAnFzF6hGRtHm1vfSD1mNnH8oyn7mKjyr7qOln7s5f8Nl85ueMolfrV3H2rCZgM2itNQ+Ezzgg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/grid": "^3.8.5",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/i18n": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.9.0.tgz",
+            "integrity": "sha512-ebGP/sVG0ZtNF4RNFzs/W01tl7waYpBManh1kKWgA4roDPFt/odkgkDBzKGl+ggBb7TQRHsfUFHuqKsrsMy9TA==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@internationalized/message": "^3.1.1",
+                "@internationalized/number": "^3.4.0",
+                "@internationalized/string": "^3.1.1",
+                "@react-aria/ssr": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/interactions": {
+            "version": "3.20.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.20.0.tgz",
+            "integrity": "sha512-JCCEyK2Nb4mEHucrgmqhTHTNAEqhsiM07jJmmY22eikxnCQnsEfdwXyg9cgZLG79D5V7jyqVRqOp2OsG7Qx7kQ==",
+            "requires": {
+                "@react-aria/ssr": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/label": {
+            "version": "3.7.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.3.tgz",
+            "integrity": "sha512-v1zuqbpYyYaPjrBWpceGjMpwP4ne6fLoOXdoIZoKLux2jkAcyIF2kIJFiyYoPQYQJWGRNo7q1oSwamxmng4xJw==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/link": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.6.2.tgz",
+            "integrity": "sha512-v9gXgQ3Gev0JOlg2MAXcubDMgX+0BlJ+hTyFYFMuN/4jVBlAe426WKbjg+6MMzxwukWg9C3Q08JzqdFTi4cBng==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/link": "^3.5.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/listbox": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.11.2.tgz",
+            "integrity": "sha512-FXdoqYLUTJn16OxodyS518PIcwzFkCfW5bxQepoy88NDMGtqp6u8fvEPpAoZbomvw/pV9MuEaMAw9qLyfkD4DA==",
+            "requires": {
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/listbox": "^3.4.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/live-announcer": {
+            "version": "3.3.1",
+            "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz",
+            "integrity": "sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/menu": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.11.2.tgz",
+            "integrity": "sha512-I4R5FOvRtwIQW+0naXav5giZBp935X2tXB2xBg/cSAYDXgfLmFPLHkyPbO77hR6FwazfFfJoKdn0pVcRox3lrQ==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/menu": "^3.5.7",
+                "@react-stately/tree": "^3.7.4",
+                "@react-types/button": "^3.9.1",
+                "@react-types/menu": "^3.9.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/meter": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.8.tgz",
+            "integrity": "sha512-u/pNisFs8UottonYlwqaS2i/NhHIw9LcApHo55XP7XMFCnaHPlq3mJzpSsr0zuCTvat2djoKelj41jT6Fhuw+A==",
+            "requires": {
+                "@react-aria/progress": "^3.4.8",
+                "@react-types/meter": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/numberfield": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.10.0.tgz",
+            "integrity": "sha512-ixkvkPTn18RNPnbaT726CHA+Wpr/qTYWboq8hSaJK0LiAtiEWCKg0pmVtJ4lFntAQ5GNp02xudTwhQdLN5WRig==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/spinbutton": "^3.6.0",
+                "@react-aria/textfield": "^3.13.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/numberfield": "^3.7.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/numberfield": "^3.7.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/overlays": {
+            "version": "3.19.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.19.0.tgz",
+            "integrity": "sha512-VN5GkB8+uZ2cfXljBtkqmrsAhBdGoj4un/agH0Qyihi2dazsMeafczSNnqzbpVgB4Zt2UHPJUkKwihgzXRxJJA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/ssr": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-stately/overlays": "^3.6.4",
+                "@react-types/button": "^3.9.1",
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/progress": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.8.tgz",
+            "integrity": "sha512-Nah3aj5BNRa0+urQZimzb0vuKQK7lsc8BrUwJuHTwGRBSWUjCADExrJYdhDIR/nLUV2TCmAQl+GJtTgbEEj0DQ==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/progress": "^3.5.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/radio": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.9.0.tgz",
+            "integrity": "sha512-kr3+OQ1YU/3mURZfCsYaQmJ/c15qOm8uScaDRC39qz97bLNASakQqMImIaS+GluPKx1PEW3y2ErAgLplH28zZw==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/radio": "^3.10.0",
+                "@react-types/radio": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/searchfield": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.6.0.tgz",
+            "integrity": "sha512-mHaN+sx2SLqluvF0/YIBQ9WA5LakSWl79FgC0sOWEaOZhDswAbJ9tESdi/M/ahtOnVwblE0cpHRlUKV0Oz4gOw==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/textfield": "^3.13.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/searchfield": "^3.5.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/searchfield": "^3.5.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/select": {
+            "version": "3.14.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.14.0.tgz",
+            "integrity": "sha512-ulVFH8K1yr8CxQE7pzhlM3aWBltWfSbWdJV3FXDqM0kA+GHqqPwZVJcqPuegtaiju1z6nRk4q789kJa4o+4M9g==",
+            "requires": {
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/listbox": "^3.11.2",
+                "@react-aria/menu": "^3.11.2",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-stately/select": "^3.6.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/select": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/selection": {
+            "version": "3.17.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.17.2.tgz",
+            "integrity": "sha512-AXXY3eOIWnITabMn6c0bpLPXkSX7040LOZU+7pQgtZJwDdZorLuKw4i7WS5i71LcV71ywG4mtqc9mOb/GfhUbg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/selection": "^3.14.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/separator": {
+            "version": "3.3.8",
+            "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.3.8.tgz",
+            "integrity": "sha512-u15HgH2IVKN/mx7Hp9dfNiFpPU/mq2EA7l0e2fsVSjA77nhSctUFBAqaR7FAI/y86RUhq3zplIz4BJek1/3Dvw==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/slider": {
+            "version": "3.7.3",
+            "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.3.tgz",
+            "integrity": "sha512-AbrTD9UzMn0CwxFjOhJHz2ms2zdJlBL3XnbvqkpsmpXUl0u8WT1QAEaMnS5+792gnSGZs/ARDmse53o+IO8wTA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/slider": "^3.4.5",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/slider": "^3.7.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/spinbutton": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.0.tgz",
+            "integrity": "sha512-I7f1gfwVRcjguEXZijk0z5g8njZ2YWnQzVzcwGf8ocLPxfw1CnSivNCzwVj2ChXPX10uXewXVMLWVCz+BRC9uQ==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/ssr": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.0.tgz",
+            "integrity": "sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/switch": {
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.5.7.tgz",
+            "integrity": "sha512-zBEsB071zzhQ82RwAA42pFLXHgrpya0OoRAsTO6jHZwiaYMsyqJI2eiXd7F6rqklpgyO6k7jOQklGUuoSJW4pA==",
+            "requires": {
+                "@react-aria/toggle": "^3.9.0",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/switch": "^3.5.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/table": {
+            "version": "3.13.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.13.2.tgz",
+            "integrity": "sha512-bJgMx2SZ8SFmTosbv6k1lZ1a0Yw3f8tzWhpIQodCaMHhtI7izA6YqDNx47NeBNYpVm9DFfAoWbb79HFJ+OKIJA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/grid": "^3.8.5",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/flags": "^3.0.0",
+                "@react-stately/table": "^3.11.3",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/checkbox": "^3.6.0",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/table": "^3.9.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/tabs": {
+            "version": "3.8.2",
+            "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.8.2.tgz",
+            "integrity": "sha512-zDfeEEyJmcnH9TFvJECWIrJpxX4SmREFV1/P8hN6ZUJPYoeiGMXYYFvjcRb1r3LN8XKlbwR37AQ3Cn1/yhrUwQ==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/tabs": "^3.6.2",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/tabs": "^3.3.4",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/tag": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.3.0.tgz",
+            "integrity": "sha512-mANJTcPyut98O4D3cAKaNEV6QFfoljZCDAgC+uJkV/Zn8cU4JOFeNLAyNoLRlPvYw+msqr6wUyPkWNERuO+1Uw==",
+            "requires": {
+                "@react-aria/gridlist": "^3.7.2",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/button": "^3.9.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/textfield": {
+            "version": "3.13.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.13.0.tgz",
+            "integrity": "sha512-sUlinDE+k/WhbskyqVOkuffuhiQpjgvp+iGRoralStVgb8Tcb+POxgAlw5jS4tNjdivCb3IjVJemUNJM7xsxxA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/textfield": "^3.9.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/toggle": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.9.0.tgz",
+            "integrity": "sha512-2YMWYQUEmcoAXtrAE86QXBS9XlmJyV6IFRlMTBNaeLTdH3AmACExgsyU66Tt0sKl6LMDMI376ItMFqAz27BBdQ==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/checkbox": "^3.6.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/tooltip": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.6.5.tgz",
+            "integrity": "sha512-hXw4Z8nYLOWz3QOQ807wWZdvDwR3gofsmZhAehg2HPRwdRfCQK+1cjVKeUd9cKCAxs0Cay7dV0oUdilLbCQ2Gg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/tooltip": "^3.4.6",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/tooltip": "^3.4.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/utils": {
+            "version": "3.22.0",
+            "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.22.0.tgz",
+            "integrity": "sha512-Qi/m65GFFljXA/ayj1m5g3KZdgbZY3jacSSqD5vNUOEGiKsn4OQcsw8RfC2c0SgtLV1hLzsfvFI1OiryPlGCcw==",
+            "requires": {
+                "@react-aria/ssr": "^3.9.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0",
+                "clsx": "^1.1.1"
+            }
+        },
+        "@react-aria/virtualizer": {
+            "version": "3.9.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/virtualizer/-/virtualizer-3.9.7.tgz",
+            "integrity": "sha512-xaLnzRypiJuGi91ns+LXLGfEhi4a2oz2ZUrZmIrMnBF3asEqULX1PEZoeSWrTWENzumM9D49fvB4JqonK0Ktwg==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-aria/visually-hidden": {
+            "version": "3.8.7",
+            "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.7.tgz",
+            "integrity": "sha512-OuIGMVQIt7GC43h4x35BgkZid8lhoPu7Xz4TQRP8nvOJWb1lH7ehrRRuGdUsK3y90nwpxTdNdg4DILblg+VaLw==",
+            "requires": {
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-google-maps/api": {
+            "version": "2.18.1",
+            "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.18.1.tgz",
+            "integrity": "sha512-KVlUO/Shh+0g/3egWaKmY0sz6+0QOnYkBGvrBMJbz23519LauA+iJFc4NDCmWNHqD5Vhb/Bkg0kSJgq0Stz3Iw==",
+            "requires": {
+                "@googlemaps/js-api-loader": "1.15.1",
+                "@googlemaps/markerclusterer": "2.0.15",
+                "@react-google-maps/infobox": "2.16.0",
+                "@react-google-maps/marker-clusterer": "2.16.1",
+                "@types/google.maps": "3.50.5",
+                "invariant": "2.2.4"
+            }
+        },
+        "@react-google-maps/infobox": {
+            "version": "2.16.0",
+            "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.16.0.tgz",
+            "integrity": "sha512-ZojiMS25388RcUHQPycUAerSqdHDom+3dHczVcXHdT/i8fka3O8InkHxXwMhvBoM143ips7mv2BPaYOAJ5f4Nw=="
+        },
+        "@react-google-maps/marker-clusterer": {
+            "version": "2.16.1",
+            "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.16.1.tgz",
+            "integrity": "sha512-jOuyqzWLeXvQcoAu6TCVWHAuko+sDt0JjawNHBGqUNLywMtTCvYP0L0PiqJZOUCUeRYGdUy0AKxQ+30vAkvwag=="
+        },
+        "@react-spectrum/actionbar": {
+            "version": "3.4.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/actionbar/-/actionbar-3.4.0.tgz",
+            "integrity": "sha512-Kb0lSo5iFpb4Qeet0fN8Ful7TFtmtHkl1LJuKz53q2qYQll+E+r2VVAdcOQMJRMRAEnecfd5mxAjEVawdOqrdw==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/live-announcer": "^3.3.1",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/actiongroup": "^3.10.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-types/actionbar": "^3.1.4",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/actiongroup": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/actiongroup/-/actiongroup-3.10.0.tgz",
+            "integrity": "sha512-Wz6nD43bSFiUJsGJr8nIlFjiDzh7ZM65a7xnkHHk+wEPU6wDR6pA0fLVsscMMgNDqDaW2RclfIpJ2jBTBqZ7/w==",
+            "requires": {
+                "@react-aria/actiongroup": "^3.7.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/menu": "^3.16.0",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/tooltip": "^3.6.2",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/actiongroup": "^3.4.6",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@spectrum-icons/workflow": "^4.2.7",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/avatar": {
+            "version": "3.0.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/avatar/-/avatar-3.0.7.tgz",
+            "integrity": "sha512-+WfgiweFfu8rIhTIEKC/4i0X97lqTWxvosjQMmAgDV2m3Z0Qf03stJzZFL9UISEF+EchE6G17bAYfZ5UjmmErQ==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/avatar": "^3.0.4",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/badge": {
+            "version": "3.1.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/badge/-/badge-3.1.8.tgz",
+            "integrity": "sha512-yplVbI2r/JJKVrsoc7cQpGv7JCPOApH6NYvjPo2UI7Vi5qI86BMP51BtHvZaxsmxKIinGBaoX44jcBcJw40Pmg==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/badge": "^3.1.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/breadcrumbs": {
+            "version": "3.9.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/breadcrumbs/-/breadcrumbs-3.9.2.tgz",
+            "integrity": "sha512-JMDeUpvzehx82mNizcc/Hnd1KYJCAnZARn9LJZpDhTqCMZW7OVkaUf8l5EtYPQpy6IAt477rQX4Gh/ipl+niLw==",
+            "requires": {
+                "@react-aria/breadcrumbs": "^3.5.8",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/menu": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-types/breadcrumbs": "^3.7.2",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/button": {
+            "version": "3.15.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/button/-/button-3.15.0.tgz",
+            "integrity": "sha512-Hr4A2ex9uxg93XsnboCgiFYSD/lh8dK4u7+0I+yZ075kinrQVfbS4x5QZKqTW/BRxMOifHqfzz1CY2FMZ+9FSA==",
+            "requires": {
+                "@react-aria/button": "^3.9.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/buttongroup": {
+            "version": "3.6.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/buttongroup/-/buttongroup-3.6.8.tgz",
+            "integrity": "sha512-KyyhNBok0bmAMVYIu7V5sNtw+sywfihF3j60yLwVCGdNl8tekLtZs8bwQY+HhkDMuyM5OPK9ClY5mMZAzDxWoQ==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/buttongroup": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/calendar": {
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/calendar/-/calendar-3.4.3.tgz",
+            "integrity": "sha512-UF5lR+zHbur1tjjE+B6dcht9+o7iu+jfCf8sXfU0HSs7DoJGiUazpOuTKG3WQhuTMcuYYewGU7zXdphEM8NGcw==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-aria/calendar": "^3.5.3",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/calendar": "^3.4.2",
+                "@react-types/button": "^3.9.1",
+                "@react-types/calendar": "^3.4.2",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/checkbox": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/checkbox/-/checkbox-3.9.0.tgz",
+            "integrity": "sha512-UDNy1qLSgvBtpsX+Df2GL7hBsnqtNPXj13lX5YflvbxqQhqMK5H838toMtbxM1fgO/JW1lD6mXOLx8TgK5WSOw==",
+            "requires": {
+                "@react-aria/checkbox": "^3.12.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/checkbox": "^3.6.0",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/checkbox": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/combobox": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/combobox/-/combobox-3.11.2.tgz",
+            "integrity": "sha512-HSgXm/dleNOG5BJ00Dju0pUlYYXgTMXJ0zgt4yVRyDKpH+vBwL60TYTP/JoVik9YrZkYd3NJ+IgaS5a5MEIXMg==",
+            "requires": {
+                "@react-aria/button": "^3.9.0",
+                "@react-aria/combobox": "^3.8.0",
+                "@react-aria/dialog": "^3.5.8",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/form": "^3.0.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/label": "^3.7.3",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/listbox": "^3.12.4",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/textfield": "^3.11.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/combobox": "^3.8.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/combobox": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/contextualhelp": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/contextualhelp/-/contextualhelp-3.6.5.tgz",
+            "integrity": "sha512-gDxB68DFXPz3odOkyVFFWJZOx5l57JXUuZnrrUXSP4TnX/snXL+1+aIBzMcXqdJJhW8OB9sYmWAkimffLMuzGA==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/dialog": "^3.8.5",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/contextualhelp": "^3.2.7",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/workflow": "^4.2.7",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/datepicker": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/datepicker/-/datepicker-3.9.0.tgz",
+            "integrity": "sha512-Hqq3/IigL939mbFtUWsr95/rr/IN9r7a2Nvquha6vg9UALk8XnTj0f3fJl6m16GdSavpfOvxz7Ef9+Vqijw0mg==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-aria/datepicker": "^3.9.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/calendar": "^3.4.3",
+                "@react-spectrum/dialog": "^3.8.5",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-spectrum/view": "^3.6.5",
+                "@react-stately/datepicker": "^3.9.0",
+                "@react-types/datepicker": "^3.7.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@spectrum-icons/workflow": "^4.2.7",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/dialog": {
+            "version": "3.8.5",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/dialog/-/dialog-3.8.5.tgz",
+            "integrity": "sha512-lkAgRhzawhOX9yEjnA1tQeb5Yyv9W4CbRYv7ZtY6pr8f35b8JQQUGKCby3A/TArW5zTBvoueoMt27gJDxnGF5w==",
+            "requires": {
+                "@react-aria/dialog": "^3.5.8",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/buttongroup": "^3.6.8",
+                "@react-spectrum/divider": "^3.5.8",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-spectrum/view": "^3.6.5",
+                "@react-stately/overlays": "^3.6.4",
+                "@react-types/button": "^3.9.1",
+                "@react-types/dialog": "^3.5.7",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/divider": {
+            "version": "3.5.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/divider/-/divider-3.5.8.tgz",
+            "integrity": "sha512-1+uIZW/TO/laTgvUpSaBuKyScpVKDXQhyWd0WyP2UioRA7gIh9rEgoMAIV4WPFUXBLdj6W12uYGOjSS2iXfzYQ==",
+            "requires": {
+                "@react-aria/separator": "^3.3.8",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/divider": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/dnd": {
+            "version": "3.3.5",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/dnd/-/dnd-3.3.5.tgz",
+            "integrity": "sha512-+lPqHd/CSbz/PV2HXIOpKLuBRpee3oz0nO0CRIog7zfIkI/wl2xaov+PdrUKk+58GUNGhz1C69QlPnDCV+t+0w==",
+            "requires": {
+                "@react-aria/dnd": "^3.5.0",
+                "@react-stately/dnd": "^3.2.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/form": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/form/-/form-3.7.0.tgz",
+            "integrity": "sha512-TrUUG6D28Ugy/CmiGJJxkr8ue4zRE3wQkC6HScNCLcVGSkrcsWzDDUxRYDrxwlyFNMuZjUDhiLMMPthZqZcIUA==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/form": "^3.0.0",
+                "@react-types/form": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/icon": {
+            "version": "3.7.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/icon/-/icon-3.7.8.tgz",
+            "integrity": "sha512-OllOy3+2laBHZNXAsVfy7J7ov9UsT/e6zTeqvWVIhYW8abpIYcCtJWxeaBPubVMcA47NRCLF46sEOuFhnTUxIw==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/illustratedmessage": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/illustratedmessage/-/illustratedmessage-3.4.8.tgz",
+            "integrity": "sha512-QHrjAZ9rXv+WpUR0QG3bz/3j1qLkc7qS4AwImZ9aoF7YRWMxLJCB2/b9tPGmWRWjjeH+gSSa4Q4y8FEr2hsYkA==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/illustratedmessage": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/image": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/image/-/image-3.4.8.tgz",
+            "integrity": "sha512-hdDFjAxF9poKsE820H37C3y8J8NBzNQx8c/Erp2O1LTQP5HynBimYxqezx5KAl9scFsOaHsbY+VdGdFTzOmIsg==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/image": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/inlinealert": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/inlinealert/-/inlinealert-3.2.0.tgz",
+            "integrity": "sha512-uRWLLl2M5tc7B3/Lzm2/JLxXOyi+cT6uYkq9eksBM41OMfvgLksT5vaOegiBGHgi2r7QktTMZnDzGk5sGvaQyA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/label": {
+            "version": "3.16.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/label/-/label-3.16.0.tgz",
+            "integrity": "sha512-VLTpsq8wxTSv5eA2LwUVW79gdja3oSAKiTZmU6dMlo3yuBOhTMAsaAbgFhopTvotjUim9JG24BRpajnuA7Jz4w==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/label": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/labeledvalue": {
+            "version": "3.1.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/labeledvalue/-/labeledvalue-3.1.8.tgz",
+            "integrity": "sha512-J/LaCVR3pWYbTg7sZg1p0W7jdWongUTjEE+2mlSdtJJaxLTUgOFgm32k/RU7foFK9+ds41S6gfDpv88aR4M+YA==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/layout": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/layout/-/layout-3.6.0.tgz",
+            "integrity": "sha512-eOG7u7dqqawMJq/cgr0Iq96Tqt2tuRVStnLgVpWJqKSYxJadd8Ja3mAkWzUq5SfX3r1w3UJWSJPcqYcu4TQ5yQ==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/layout": "^3.3.12",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/link": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/link/-/link-3.6.2.tgz",
+            "integrity": "sha512-Pa3fgGUpxzlWZ6fXVQcdLXDxp6Ui9KtJDSKZYAxQrTL4OzEA8rgF+FeG0d7MDAHW2okW6a/N9dJALrJEtlizGg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/link": "^3.6.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/link": "^3.5.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/list": {
+            "version": "3.7.4",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/list/-/list-3.7.4.tgz",
+            "integrity": "sha512-ccMeyylTWknzZoWHGGDzmaPHKU2hns0UjHBDyNT8hCItO/YL0s2NWY83QO+iYS8Xb6n/EDts7IBrJJYrmxDRWQ==",
+            "requires": {
+                "@react-aria/button": "^3.9.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/gridlist": "^3.7.2",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/virtualizer": "^3.9.7",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-spectrum/checkbox": "^3.9.0",
+                "@react-spectrum/dnd": "^3.3.5",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/layout": "^3.13.4",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0",
+                "react-transition-group": "^4.4.5"
+            }
+        },
+        "@react-spectrum/listbox": {
+            "version": "3.12.4",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/listbox/-/listbox-3.12.4.tgz",
+            "integrity": "sha512-qmgHbeoFMFAK3AViPWri2z0Aqio0h2pf0ROjjkNPmTIm9xZEFMwArLqWhftmEm+smMTuNLjZv8aYGahKwiQDrg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/listbox": "^3.11.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/virtualizer": "^3.9.7",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/layout": "^3.13.4",
+                "@react-stately/list": "^3.10.1",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/listbox": "^3.4.6",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/menu": {
+            "version": "3.16.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/menu/-/menu-3.16.0.tgz",
+            "integrity": "sha512-wcUwBLifWvJvMQrdnh7+m9g4maW87zv7yB2D/cnGYIkXL1aNZxa6zHLxSegs1PrqdP77fhEXthVFcMreuIHO6A==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/menu": "^3.11.2",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/separator": "^3.3.8",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/menu": "^3.5.7",
+                "@react-stately/overlays": "^3.6.4",
+                "@react-stately/tree": "^3.7.4",
+                "@react-types/menu": "^3.9.6",
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@spectrum-icons/workflow": "^4.2.7",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/meter": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/meter/-/meter-3.4.8.tgz",
+            "integrity": "sha512-7nFE+B9OE6WyKJpBn8gAulNAlKqG2VFq74UiB/xV37rHXRIjn4waLaxK7s6uHCozOu2Ly5uTDJV5x3AN3W2ldw==",
+            "requires": {
+                "@react-aria/meter": "^3.4.8",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/meter": "^3.3.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/numberfield": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/numberfield/-/numberfield-3.8.0.tgz",
+            "integrity": "sha512-uboKuVBDYR5BkGw1qY3udKmsMRipkhQIY1diKK0uu5ETdKrjhXRNQ5L+xfshT/K960tmztwnKk/nj1jePjk6MA==",
+            "requires": {
+                "@react-aria/button": "^3.9.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/numberfield": "^3.10.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/textfield": "^3.11.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/numberfield": "^3.7.0",
+                "@react-types/button": "^3.9.1",
+                "@react-types/numberfield": "^3.7.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@spectrum-icons/workflow": "^4.2.7",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/overlays": {
+            "version": "5.5.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/overlays/-/overlays-5.5.2.tgz",
+            "integrity": "sha512-4VXK1HMazuETgSnpPSPszuCB/4WaVhPX0h+1ICllReuvv9mvgWt6KoCkqJSoVMM8qlB4XocGUPsI1pL+Bck78w==",
+            "requires": {
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/overlays": "^3.6.4",
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0",
+                "react-transition-group": "^4.4.5"
+            }
+        },
+        "@react-spectrum/picker": {
+            "version": "3.13.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/picker/-/picker-3.13.2.tgz",
+            "integrity": "sha512-o7t1tnCKrYbDpZ/n3vohok82Yx6iEv8TQXUrXkiqHbRiohN72PB4WJMOlBjMbNaprcC4tdkHVuGlAhSwQHYBdA==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/select": "^3.14.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/listbox": "^3.12.4",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/select": "^3.6.0",
+                "@react-types/select": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/progress": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/progress/-/progress-3.7.2.tgz",
+            "integrity": "sha512-YtAvWHC4rwBqRagoS/Mmt2NOZo4G6p5rIdhiVp/UjKa1oqEEiut29dMvr/JS30AoNPPSc95ctydgUU6JynyGJQ==",
+            "requires": {
+                "@react-aria/progress": "^3.4.8",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/progress": "^3.5.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/provider": {
+            "version": "3.9.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/provider/-/provider-3.9.2.tgz",
+            "integrity": "sha512-5DZA8UdAXWzLJo7nxO7VgTqvmjN6cbjctMWhLbv81jSLWRqm+O6RhRZjnbEVXqwfyPpxJzDG8ZhjaQe/kFs38A==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/provider": "^3.7.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0",
+                "clsx": "^1.1.1"
+            }
+        },
+        "@react-spectrum/radio": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/radio/-/radio-3.7.0.tgz",
+            "integrity": "sha512-AikFzw+aJ1gL6Ysnfb4wXDgsnPp0KB9jbMrqENW6KKZxQ5+au2Xzj28mnKDfAjBXlxQlTAhBo5SnI0WnjTmKWA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/radio": "^3.9.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/radio": "^3.10.0",
+                "@react-types/radio": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/searchfield": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/searchfield/-/searchfield-3.8.0.tgz",
+            "integrity": "sha512-WVI/5ONt1hSm+D/A7J3ICpVOue6J2FBBWKU9zVSK7cwcklWgUGyGkZLD8luVQtcpI5bDLb2tHixs7a1OXPC8Uw==",
+            "requires": {
+                "@react-aria/searchfield": "^3.6.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/textfield": "^3.11.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/searchfield": "^3.5.0",
+                "@react-types/searchfield": "^3.5.2",
+                "@react-types/textfield": "^3.9.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/slider": {
+            "version": "3.6.4",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/slider/-/slider-3.6.4.tgz",
+            "integrity": "sha512-ckKlRJhDKUIsZepnCzRcCe20Q4MaoC8dLEFNz/f6CItfZNoE8sH5OsHuDFOEbhNOgNyGjj9Dv99iKPAkRrDWkg==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/slider": "^3.7.3",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/slider": "^3.4.5",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/slider": "^3.7.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/statuslight": {
+            "version": "3.5.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/statuslight/-/statuslight-3.5.8.tgz",
+            "integrity": "sha512-q0q/JzEmucU83fCGokIQZ09/TsFWKuv+eHm2FKRZNeLcTS1oGNZGsty7iFa7To+b4F3lA7HxEQ936EOjQuDOwQ==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/statuslight": "^3.3.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/switch": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/switch/-/switch-3.5.0.tgz",
+            "integrity": "sha512-a9SbC3seaU/Ai840q1PZEZraB3EJosDqww0zKU80pDtTqtP4b3KWwvHrVRWOQ2PeJm1bm/aPkuyMa7cM12m2tQ==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/switch": "^3.5.7",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/toggle": "^3.7.0",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/switch": "^3.5.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/table": {
+            "version": "3.12.4",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/table/-/table-3.12.4.tgz",
+            "integrity": "sha512-29dWRfs0rZv4PXByyRZPdgPVQiyjZAm4hFhvqmZnpeKQx3+Y63MrO0xdDYIIbopmANhKT/JPO3jIG4gWMvd72A==",
+            "requires": {
+                "@react-aria/button": "^3.9.0",
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/table": "^3.13.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-aria/virtualizer": "^3.9.7",
+                "@react-aria/visually-hidden": "^3.8.7",
+                "@react-spectrum/checkbox": "^3.9.0",
+                "@react-spectrum/dnd": "^3.3.5",
+                "@react-spectrum/layout": "^3.6.0",
+                "@react-spectrum/menu": "^3.16.0",
+                "@react-spectrum/progress": "^3.7.2",
+                "@react-spectrum/tooltip": "^3.6.2",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/flags": "^3.0.0",
+                "@react-stately/layout": "^3.13.4",
+                "@react-stately/table": "^3.11.3",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/table": "^3.9.1",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/tabs": {
+            "version": "3.8.4",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tabs/-/tabs-3.8.4.tgz",
+            "integrity": "sha512-wDMHf8Xa3lCh7vkkpwT3G8Vd6ooo5VSHlMv1NUQsFjlymbZQ88aBkZfJVBxag7fWoO/Yo2IGf5Tb2Gpj1hW99Q==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/tabs": "^3.8.2",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/picker": "^3.13.2",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/list": "^3.10.1",
+                "@react-stately/tabs": "^3.6.2",
+                "@react-types/select": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/tabs": "^3.3.4",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/tag": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tag/-/tag-3.2.0.tgz",
+            "integrity": "sha512-BrYpyaoJkaHL/74DzaCJjMzn544TvJbf9uJaZ3TUwt8MQ4rAOdHKn5fI3jiX665WWJPhsI6Dfns/gN/4HlqfJA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/selection": "^3.17.2",
+                "@react-aria/tag": "^3.3.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/button": "^3.15.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/text": "^3.5.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/list": "^3.10.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/text": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/text/-/text-3.5.0.tgz",
+            "integrity": "sha512-gZ2sqrfz/T8kYhS/TUXoR6ZhC9apU1i+K+8W9LV7LXAraZYQiDTiglTqnxER+qtW/+Xon1ZDoL2TICt63wHFFA==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/text": "^3.3.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/textfield": {
+            "version": "3.11.0",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/textfield/-/textfield-3.11.0.tgz",
+            "integrity": "sha512-bAG4hwFUJGWiViaOBXDWvYxsMvzs8+rCfdiLil7b5CPgbZCpvsHVMSt8dOQW18MqrJNGv2Zm8gZYjvFSnfklAA==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/interactions": "^3.20.0",
+                "@react-aria/textfield": "^3.13.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/form": "^3.7.0",
+                "@react-spectrum/label": "^3.16.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/textfield": "^3.9.0",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/theme-dark": {
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-dark/-/theme-dark-3.5.7.tgz",
+            "integrity": "sha512-WaBVkhJKsZNcsHCcm6HQOSV934KLxZK6cbTt/FjUZtNTHcQTb5s2xf2jPeMwcRbRJfzagfTuTr5BkM38B9Zi1Q==",
+            "requires": {
+                "@react-types/provider": "^3.7.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/theme-default": {
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-default/-/theme-default-3.5.7.tgz",
+            "integrity": "sha512-5GgCKfzA1be3pE5XtQ+5hk39I4BhU1qY+fHCDxvE/tndm2I7pCk26d6ifxA0H2RVKH8V3eiH0WG1TNXHcHIO1g==",
+            "requires": {
+                "@react-types/provider": "^3.7.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/theme-light": {
+            "version": "3.4.7",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/theme-light/-/theme-light-3.4.7.tgz",
+            "integrity": "sha512-3NeIDN9QU8c40rqRSzurTdJRTZ5Uag4c2fLlF9Bve/yF7N6KlzK29H3EWNLBizAfozhPe5/HDEYqdArz7bxhlQ==",
+            "requires": {
+                "@react-types/provider": "^3.7.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/tooltip": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/tooltip/-/tooltip-3.6.2.tgz",
+            "integrity": "sha512-aZ0CSlWOGgRQe/u41PgCgiXdO7+GowGE8CA46BCA8DEoqrw3JjSOX2JYClrPUra1VxHXId8AeQGU5bRw3abb2g==",
+            "requires": {
+                "@react-aria/focus": "^3.15.0",
+                "@react-aria/overlays": "^3.19.0",
+                "@react-aria/tooltip": "^3.6.5",
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/overlays": "^5.5.2",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-stately/tooltip": "^3.4.6",
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/tooltip": "^3.4.6",
+                "@spectrum-icons/ui": "^3.6.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/utils": {
+            "version": "3.11.2",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/utils/-/utils-3.11.2.tgz",
+            "integrity": "sha512-JLv0ntBrrIvloUgqVhAZvTTiBqZ/pHtAWOuIgrii3PFUsds4OVX+YebB88rj639Zi/tFrSdfrlZJNER1ZOq9jw==",
+            "requires": {
+                "@react-aria/i18n": "^3.9.0",
+                "@react-aria/ssr": "^3.9.0",
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0",
+                "clsx": "^1.1.1"
+            }
+        },
+        "@react-spectrum/view": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/view/-/view-3.6.5.tgz",
+            "integrity": "sha512-y135Ownoi6Hw466k4hWcYBJmqjTQlKVgXtCT5aKpKm8l9RlpvPvtoUe5OBUxKkHHgB1TCIOpy76hLi9SQc0Omw==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/view": "^3.4.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-spectrum/well": {
+            "version": "3.4.8",
+            "resolved": "https://registry.npmjs.org/@react-spectrum/well/-/well-3.4.8.tgz",
+            "integrity": "sha512-A2fJxlT/eAKyPTbCOmoUNB+BjDP8RnViZ7X6/gcxjEAtn5KVnJ6DmZTG8Kw+yPnuLxK+5Lui/dfGI9g19GWohw==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-spectrum/utils": "^3.11.2",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/well": "^3.3.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/calendar": {
+            "version": "3.4.2",
+            "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.4.2.tgz",
+            "integrity": "sha512-RfH40rVa2EhUnQgqH3HTZL+YhL+6tZ8T9GbN1K3AbIM5BBEtkb3P8qGhcaI7WpwNy1rlRFFFXGcqFAMUncDg2Q==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/calendar": "^3.4.2",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/checkbox": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.0.tgz",
+            "integrity": "sha512-e1ChMwGovcOEDcdizqXDT6eDZixIMiPQOzNV5wPQ91SlGaIry9b0lQnK18tHg3yv2iiS6Ipj96cGBUKLJqQ+cQ==",
+            "requires": {
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/checkbox": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/collections": {
+            "version": "3.10.3",
+            "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.10.3.tgz",
+            "integrity": "sha512-fA28HIApAIz9sNGeOVXZJPgV5Kig6M72KI1t9sUbnRUr9Xq9OMJTR6ElDMXNe0iTeZffRFDOPYyqnX9zkxof6Q==",
+            "requires": {
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/combobox": {
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.8.0.tgz",
+            "integrity": "sha512-F74Avf7+8ruRqEB+3Lh6/C5jXc3ESJbRf9ovUxhmNAzBGeFKesPn5HpEpo87C+3OukGb+/Buvi3Rhib9+HVBKA==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/list": "^3.10.1",
+                "@react-stately/menu": "^3.5.7",
+                "@react-stately/select": "^3.6.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/combobox": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/data": {
+            "version": "3.11.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/data/-/data-3.11.0.tgz",
+            "integrity": "sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q==",
+            "requires": {
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/datepicker": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.9.0.tgz",
+            "integrity": "sha512-p6BuxPbDxjIgBZmskdv2dR6XIdPEftCjS7kYe/+iLZxfz1vYiDqpJVb3ascLyBjl84bDDyr4z2vWcKhdDwyhEA==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@internationalized/string": "^3.1.1",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/overlays": "^3.6.4",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/datepicker": "^3.7.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/dnd": {
+            "version": "3.2.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.2.6.tgz",
+            "integrity": "sha512-ex3Pjn+9uIoqsBb9F4ZFJb3fB0YadN8uYBOEiBb9N4UXWyANibGUYJ2FvIbvq1nFDU7On7MW1J9e3vkGglX4FQ==",
+            "requires": {
+                "@react-stately/selection": "^3.14.1",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/flags": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.0.0.tgz",
+            "integrity": "sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w==",
+            "requires": {
+                "@swc/helpers": "^0.4.14"
+            },
+            "dependencies": {
+                "@swc/helpers": {
+                    "version": "0.4.36",
+                    "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.36.tgz",
+                    "integrity": "sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q==",
+                    "requires": {
+                        "legacy-swc-helpers": "npm:@swc/helpers@=0.4.14",
+                        "tslib": "^2.4.0"
+                    },
+                    "dependencies": {
+                        "legacy-swc-helpers": {
+                            "version": "npm:@swc/helpers@0.4.14",
+                            "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz",
+                            "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==",
+                            "requires": {
+                                "tslib": "^2.4.0"
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        "@react-stately/form": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.0.0.tgz",
+            "integrity": "sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/grid": {
+            "version": "3.8.3",
+            "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.8.3.tgz",
+            "integrity": "sha512-JceGSJcuO6Zv+Aq5s2NZvmbMjdPjTtGNQR9kTgXKC/pOfM6FJ58bJiOmEllyN6oawqh4Ey8Xdqk9NuW4l2ctuw==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/selection": "^3.14.1",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/layout": {
+            "version": "3.13.4",
+            "resolved": "https://registry.npmjs.org/@react-stately/layout/-/layout-3.13.4.tgz",
+            "integrity": "sha512-gmtkB+EISfB1Ne/56cd4djJXUwCtcrjzA7BHzBBXcjJNmTc/NQh5+qh66JHkXTKF3PT5FdVtmO2MODqGaWkUeg==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/table": "^3.11.3",
+                "@react-stately/virtualizer": "^3.6.5",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/table": "^3.9.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/list": {
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.10.1.tgz",
+            "integrity": "sha512-iVarLMd7FmMT0H20dRWsFOHHX5+c4gK51AXP2BSr1VtDSfbL4dgaGgu7IaAMVc/rO0au1e1tPM2hutiIFvPcnA==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/selection": "^3.14.1",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/menu": {
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.5.7.tgz",
+            "integrity": "sha512-bzTmAqzcMNatvyruWlvOdZSmMhz3+mkdxtqaZzYHq+DpR6ka57lIRj8dBnZWQGwV3RypMZfz+X6aIX4kruGVbw==",
+            "requires": {
+                "@react-stately/overlays": "^3.6.4",
+                "@react-types/menu": "^3.9.6",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/numberfield": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.7.0.tgz",
+            "integrity": "sha512-DOz4jL7T30KGUXpGh/z80aHf+DEOQfvCHVDfll+IU7p3sd+bbM5uj7JdwXpZgIYUK8KTf2N49sL6lq5uCoxh8w==",
+            "requires": {
+                "@internationalized/number": "^3.4.0",
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/numberfield": "^3.7.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/overlays": {
+            "version": "3.6.4",
+            "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.4.tgz",
+            "integrity": "sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA==",
+            "requires": {
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/overlays": "^3.8.4",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/radio": {
+            "version": "3.10.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.0.tgz",
+            "integrity": "sha512-d8IgZtUq/4vhE7YhyBVg1QdVoFS0caIcvPumXqtp/5vlDgpUsVy9jSeWtbk0H4FyUcmJlQhRcTylKB9THXY1YQ==",
+            "requires": {
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/radio": "^3.6.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/searchfield": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.0.tgz",
+            "integrity": "sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw==",
+            "requires": {
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/searchfield": "^3.5.2",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/select": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.0.tgz",
+            "integrity": "sha512-GvSE4DXmcvdRNUc+ciPU7gedt7LfRO8FFFIzhB/bCQhUlK6/xihUPrGXayzqxLeTQKttMH323LuYFKfwpJRhsA==",
+            "requires": {
+                "@react-stately/form": "^3.0.0",
+                "@react-stately/list": "^3.10.1",
+                "@react-stately/menu": "^3.5.7",
+                "@react-types/select": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/selection": {
+            "version": "3.14.1",
+            "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.14.1.tgz",
+            "integrity": "sha512-96/CerrB6yH4Ad9FkzBzyVerSPjcIj1NBTWTFHo1N+oHECvyGsDxZl7Y4LQR++teFK66FhX5KjCJQGae4IZd6A==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/slider": {
+            "version": "3.4.5",
+            "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.4.5.tgz",
+            "integrity": "sha512-lJPZC8seYbnZDqAlZm3/QC95I5iluG8ouwkPMmvtWCz1baayV/jJtfxA/74zR7Vcob9Fe7O57g8Edhz/hv9xOQ==",
+            "requires": {
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/slider": "^3.7.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/table": {
+            "version": "3.11.3",
+            "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.11.3.tgz",
+            "integrity": "sha512-r0rzSKbtMG4tjFpCGtXb8p6hOuek03c6rheJE88z4I/ujZ5EmEO6Ps8q0JMNEDCY2qigvKM+ODisMBeZCEkIJg==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/flags": "^3.0.0",
+                "@react-stately/grid": "^3.8.3",
+                "@react-stately/selection": "^3.14.1",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/table": "^3.9.1",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/tabs": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.6.2.tgz",
+            "integrity": "sha512-f+U4D1FAVfVVcNRbtKIv4GrO37CLFClYQlXx9zIuSXjHsviapVD2IQSyAmpKo/CbgXhYRMdGwENZdOsmF/Ns7g==",
+            "requires": {
+                "@react-stately/list": "^3.10.1",
+                "@react-types/shared": "^3.22.0",
+                "@react-types/tabs": "^3.3.4",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/toggle": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.7.0.tgz",
+            "integrity": "sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g==",
+            "requires": {
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/checkbox": "^3.6.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/tooltip": {
+            "version": "3.4.6",
+            "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.4.6.tgz",
+            "integrity": "sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA==",
+            "requires": {
+                "@react-stately/overlays": "^3.6.4",
+                "@react-types/tooltip": "^3.4.6",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/tree": {
+            "version": "3.7.4",
+            "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.7.4.tgz",
+            "integrity": "sha512-0yvVODBS8WnSivLFX5ccEjCl2NA/8lbEt1E48wVcY1xcXgISNpw5MSGK5jC6YrtJPIqVolQIkNSbMreXGBktIg==",
+            "requires": {
+                "@react-stately/collections": "^3.10.3",
+                "@react-stately/selection": "^3.14.1",
+                "@react-stately/utils": "^3.9.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/utils": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.9.0.tgz",
+            "integrity": "sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw==",
+            "requires": {
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-stately/virtualizer": {
+            "version": "3.6.5",
+            "resolved": "https://registry.npmjs.org/@react-stately/virtualizer/-/virtualizer-3.6.5.tgz",
+            "integrity": "sha512-v0cZeNCGPMeo3LP4UrGuDo3Xpq7ufNaZyGObgSvdrIW49qK5F02kczcKy6NKg+QfOgC/+Nc9Tof/2S8dcxDrCA==",
+            "requires": {
+                "@react-aria/utils": "^3.22.0",
+                "@react-types/shared": "^3.22.0",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@react-three/fiber": {
+            "version": "6.2.3",
+            "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-6.2.3.tgz",
+            "integrity": "sha512-XuL3683iVcwjm3enour57k4OjkA1MQztqpRL2oQh30v7ygf1vJg95gKo8cqqgPJctc2pZAMUW1eRpr+Xqjwqrg==",
+            "requires": {
+                "@babel/runtime": "^7.13.10",
+                "react-merge-refs": "^1.1.0",
+                "react-reconciler": "^0.26.2",
+                "react-three-fiber": "0.0.0-deprecated",
+                "react-use-measure": "^2.0.4",
+                "resize-observer-polyfill": "^1.5.1",
+                "scheduler": "^0.20.2",
+                "use-asset": "^1.0.4",
+                "utility-types": "^3.10.0",
+                "zustand": "^3.5.1"
+            }
+        },
+        "@react-types/actionbar": {
+            "version": "3.1.4",
+            "resolved": "https://registry.npmjs.org/@react-types/actionbar/-/actionbar-3.1.4.tgz",
+            "integrity": "sha512-/z9N7ztd/MOdEDQNHTCNviYe0+rqy1s19Xg3tv/PV1oUCOsjrnja85VVxoa+AWR8IbwgDNIfpXg2Wa66b1FDbw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/actiongroup": {
+            "version": "3.4.6",
+            "resolved": "https://registry.npmjs.org/@react-types/actiongroup/-/actiongroup-3.4.6.tgz",
+            "integrity": "sha512-Dho2mEDCU9ZAW+QX2HZkZhyxHK/EGfTvSWdHBFaCYsh4CPI/6PcvtirpSKMrzNNaZ97Exthv3GcLpAnLwM9jZw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/avatar": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/@react-types/avatar/-/avatar-3.0.4.tgz",
+            "integrity": "sha512-fQ+qGce0EqcX0s2glnFjfvxSq42GHaqvl+eL8TnsDz0OIvB8KKzTO/rV/q1CIy/LtMP8fjCb6oqVFQcLfuODfw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/badge": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/@react-types/badge/-/badge-3.1.6.tgz",
+            "integrity": "sha512-6xjgfRnCVSBI6l/RQkI4u3tXiXw1aeFKRqXPcyIyt/kuu7rP0nKeYcM2XYyXXQp7vHfBdOEL2f6LwIHR/lx4uQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/breadcrumbs": {
+            "version": "3.7.2",
+            "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.2.tgz",
+            "integrity": "sha512-esl6RucDW2CNMsApJxNYfMtDaUcfLlwKMPH/loYsOBbKxGl2HsgVLMcdpjEkTRs2HCTNCbBXWpeU8AY77t+bsw==",
+            "requires": {
+                "@react-types/link": "^3.5.2",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/button": {
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.1.tgz",
+            "integrity": "sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/buttongroup": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/buttongroup/-/buttongroup-3.3.6.tgz",
+            "integrity": "sha512-aKFDzAWM6bk2+EBDSZe3zq4NMuguXsPyZ9OexN0YLleK4IkRKE2S51PdChY/GAFhfs7VsOKgjHrYWUnrmCCYvw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/calendar": {
+            "version": "3.4.2",
+            "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.4.2.tgz",
+            "integrity": "sha512-tCZ21un/8OAhpNtmSXDkOVvS5Pzp+y/JwNr6VGFi8HBC5F/c8SzuwV0jKN8ymsZSWbDQ68xXGNWxFaG43Bw8Pg==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/checkbox": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.6.0.tgz",
+            "integrity": "sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/combobox": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.9.0.tgz",
+            "integrity": "sha512-VAQWM2jrIWROgcTKxj4k37WWpK/1zRjj1HfGeuenAQyOQwImqDwCHx5YxQR1GiUEFne4v1yXe2khT0T5Kt2vDg==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/contextualhelp": {
+            "version": "3.2.7",
+            "resolved": "https://registry.npmjs.org/@react-types/contextualhelp/-/contextualhelp-3.2.7.tgz",
+            "integrity": "sha512-BHwBSBhPekKc/PxDpnkvfcEgpaYLMrV6WYgMfUz2/BMYOjdm+pb1y80vpNkWtrJKytyqp1zeZ+Ca+xzX1HdazA==",
+            "requires": {
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/datepicker": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.7.0.tgz",
+            "integrity": "sha512-Uh+p6pZpMFc5ZBOns5TXCBbUvJp1KVROLBn2gk5dMEFVq78Qs1VFuAt4lwr9gQBOJrX5I/l65pRTwwWwAKxYtQ==",
+            "requires": {
+                "@internationalized/date": "^3.5.0",
+                "@react-types/calendar": "^3.4.2",
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/dialog": {
+            "version": "3.5.7",
+            "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.7.tgz",
+            "integrity": "sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w==",
+            "requires": {
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/divider": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/divider/-/divider-3.3.6.tgz",
+            "integrity": "sha512-Iwwe349IiCX7ZQK1Oz4AN5kWwiXG0DECSN4qB3h+14n97JKy3chWJC7UA+V6+2p5DbxmLVZm4XxDRgx7y0lVTg==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/form": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-types/form/-/form-3.6.0.tgz",
+            "integrity": "sha512-+k6IpjQE+sVi/xoK5lnRGyeISkOQ+CKfuH8IeGcYVHr2voDxSJC5WZsp+L5zeoxuSorKokeEPKGOX2HFj9BG/A==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/grid": {
+            "version": "3.2.3",
+            "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.3.tgz",
+            "integrity": "sha512-GQM4RDmYhstcYZ0Odjq+xUwh1fhLmRebG6qMM8OXHTPQ77nhl3wc1UTGRhZm6mzEionplSRx4GCpEMEHMJIU0w==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/illustratedmessage": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/illustratedmessage/-/illustratedmessage-3.3.6.tgz",
+            "integrity": "sha512-1FdJl1tR6mirmXT8yaTFeHNWdLXV6Dll66Mv1liEtTYsmCgn2anxwM73jK63t3jdT6ez/M1wGiwMlMtyiqo+ZQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/image": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/image/-/image-3.3.6.tgz",
+            "integrity": "sha512-GSb0deyquS3kFt0e9SfPP9I/YaYYUToYYPzx9As0R0mzuVn6qTHhUtpKhBqQAOpE1Cd8XdEQeYsDB3sdOurI+A==",
             "requires": {
-                "@octokit/types": "^9.0.0"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@octokit/core": {
-            "version": "4.2.0",
-            "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.0.tgz",
-            "integrity": "sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg==",
+        "@react-types/label": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-types/label/-/label-3.9.0.tgz",
+            "integrity": "sha512-nTmPf5ED8aLGqvFsZHIHwMPrRX0cfbOyayva//Rdis41KWQoKUB80DIQjE+iUDOgTivIxGBkpqdIZVqRuehTnw==",
             "requires": {
-                "@octokit/auth-token": "^3.0.0",
-                "@octokit/graphql": "^5.0.0",
-                "@octokit/request": "^6.0.0",
-                "@octokit/request-error": "^3.0.0",
-                "@octokit/types": "^9.0.0",
-                "before-after-hook": "^2.2.0",
-                "universal-user-agent": "^6.0.0"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@octokit/endpoint": {
-            "version": "7.0.5",
-            "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.5.tgz",
-            "integrity": "sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA==",
+        "@react-types/layout": {
+            "version": "3.3.12",
+            "resolved": "https://registry.npmjs.org/@react-types/layout/-/layout-3.3.12.tgz",
+            "integrity": "sha512-Ai6limgTVYQoGiXUvsXg8MHik+YAtRWEVLQhT5E1nQkDkNkQyccB+waUSfORhRkjJcnp+KMcbmPZ8V5ZO42rvQ==",
             "requires": {
-                "@octokit/types": "^9.0.0",
-                "is-plain-object": "^5.0.0",
-                "universal-user-agent": "^6.0.0"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@octokit/graphql": {
-            "version": "5.0.5",
-            "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.5.tgz",
-            "integrity": "sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ==",
+        "@react-types/link": {
+            "version": "3.5.2",
+            "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.2.tgz",
+            "integrity": "sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw==",
             "requires": {
-                "@octokit/request": "^6.0.0",
-                "@octokit/types": "^9.0.0",
-                "universal-user-agent": "^6.0.0"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@octokit/openapi-types": {
-            "version": "16.0.0",
-            "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-16.0.0.tgz",
-            "integrity": "sha512-JbFWOqTJVLHZSUUoF4FzAZKYtqdxWu9Z5m2QQnOyEa04fOFljvyh7D3GYKbfuaSWisqehImiVIMG4eyJeP5VEA=="
+        "@react-types/listbox": {
+            "version": "3.4.6",
+            "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.4.6.tgz",
+            "integrity": "sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
         },
-        "@octokit/request": {
-            "version": "6.2.3",
-            "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.3.tgz",
-            "integrity": "sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA==",
+        "@react-types/menu": {
+            "version": "3.9.6",
+            "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.6.tgz",
+            "integrity": "sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg==",
             "requires": {
-                "@octokit/endpoint": "^7.0.0",
-                "@octokit/request-error": "^3.0.0",
-                "@octokit/types": "^9.0.0",
-                "is-plain-object": "^5.0.0",
-                "node-fetch": "^2.6.7",
-                "universal-user-agent": "^6.0.0"
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@octokit/request-error": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
-            "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
+        "@react-types/meter": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.3.6.tgz",
+            "integrity": "sha512-1XYp1fA9UU0lO6kjf3TwVE8mppOJa64mBKAcLWtTyq1e/cYIAbx5o6CsuUx0YDpXKF6gdtvIWvfmxeWsmqJ1jQ==",
             "requires": {
-                "@octokit/types": "^9.0.0",
-                "deprecation": "^2.0.0",
-                "once": "^1.4.0"
+                "@react-types/progress": "^3.5.1"
             }
         },
-        "@octokit/types": {
-            "version": "9.0.0",
-            "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.0.0.tgz",
-            "integrity": "sha512-LUewfj94xCMH2rbD5YJ+6AQ4AVjFYTgpp6rboWM5T7N3IsIF65SBEOVcYMGAEzO/kKNiNaW4LoWtoThOhH06gw==",
+        "@react-types/numberfield": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.7.0.tgz",
+            "integrity": "sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w==",
             "requires": {
-                "@octokit/openapi-types": "^16.0.0"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@opentelemetry/api": {
-            "version": "1.4.1",
-            "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz",
-            "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA=="
+        "@react-types/overlays": {
+            "version": "3.8.4",
+            "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.4.tgz",
+            "integrity": "sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
         },
-        "@pkgjs/parseargs": {
-            "version": "0.11.0",
-            "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
-            "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
-            "optional": true
+        "@react-types/progress": {
+            "version": "3.5.1",
+            "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.1.tgz",
+            "integrity": "sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
         },
-        "@popperjs/core": {
-            "version": "2.11.7",
-            "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz",
-            "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw=="
+        "@react-types/provider": {
+            "version": "3.7.1",
+            "resolved": "https://registry.npmjs.org/@react-types/provider/-/provider-3.7.1.tgz",
+            "integrity": "sha512-WKwHwG5b0LkI570tbHCy4hBhT/E+OrdgIybScDxM713B2OwmMKKyaPKdV05SeoomP8oiPvkaAeXhLZa1ah7CYg==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
         },
-        "@react-google-maps/api": {
-            "version": "2.18.1",
-            "resolved": "https://registry.npmjs.org/@react-google-maps/api/-/api-2.18.1.tgz",
-            "integrity": "sha512-KVlUO/Shh+0g/3egWaKmY0sz6+0QOnYkBGvrBMJbz23519LauA+iJFc4NDCmWNHqD5Vhb/Bkg0kSJgq0Stz3Iw==",
+        "@react-types/radio": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.6.0.tgz",
+            "integrity": "sha512-VOZzegxxZS55gHRVyWu278Q4y/rEQGiAVQCUqi25GmpbMe4MlHrzg16c76RiZMUK9PPoyv+XNUgAaPmxebkn7g==",
             "requires": {
-                "@googlemaps/js-api-loader": "1.15.1",
-                "@googlemaps/markerclusterer": "2.0.15",
-                "@react-google-maps/infobox": "2.16.0",
-                "@react-google-maps/marker-clusterer": "2.16.1",
-                "@types/google.maps": "3.50.5",
-                "invariant": "2.2.4"
+                "@react-types/shared": "^3.22.0"
             }
         },
-        "@react-google-maps/infobox": {
-            "version": "2.16.0",
-            "resolved": "https://registry.npmjs.org/@react-google-maps/infobox/-/infobox-2.16.0.tgz",
-            "integrity": "sha512-ZojiMS25388RcUHQPycUAerSqdHDom+3dHczVcXHdT/i8fka3O8InkHxXwMhvBoM143ips7mv2BPaYOAJ5f4Nw=="
+        "@react-types/searchfield": {
+            "version": "3.5.2",
+            "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.2.tgz",
+            "integrity": "sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA==",
+            "requires": {
+                "@react-types/shared": "^3.22.0",
+                "@react-types/textfield": "^3.9.0"
+            }
         },
-        "@react-google-maps/marker-clusterer": {
-            "version": "2.16.1",
-            "resolved": "https://registry.npmjs.org/@react-google-maps/marker-clusterer/-/marker-clusterer-2.16.1.tgz",
-            "integrity": "sha512-jOuyqzWLeXvQcoAu6TCVWHAuko+sDt0JjawNHBGqUNLywMtTCvYP0L0PiqJZOUCUeRYGdUy0AKxQ+30vAkvwag=="
+        "@react-types/select": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.0.tgz",
+            "integrity": "sha512-0nalGmcoma4jreICLSJae/uKAuMiVyWgqWjGrGiUGGcdDchH4limKVEqNDaBwLvxVT6NB5LLsaipCTCAEEl4Rg==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
         },
-        "@react-three/fiber": {
-            "version": "6.2.3",
-            "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-6.2.3.tgz",
-            "integrity": "sha512-XuL3683iVcwjm3enour57k4OjkA1MQztqpRL2oQh30v7ygf1vJg95gKo8cqqgPJctc2pZAMUW1eRpr+Xqjwqrg==",
+        "@react-types/shared": {
+            "version": "3.22.0",
+            "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.22.0.tgz",
+            "integrity": "sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA=="
+        },
+        "@react-types/slider": {
+            "version": "3.7.0",
+            "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.0.tgz",
+            "integrity": "sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q==",
             "requires": {
-                "@babel/runtime": "^7.13.10",
-                "react-merge-refs": "^1.1.0",
-                "react-reconciler": "^0.26.2",
-                "react-three-fiber": "0.0.0-deprecated",
-                "react-use-measure": "^2.0.4",
-                "resize-observer-polyfill": "^1.5.1",
-                "scheduler": "^0.20.2",
-                "use-asset": "^1.0.4",
-                "utility-types": "^3.10.0",
-                "zustand": "^3.5.1"
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/statuslight": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/statuslight/-/statuslight-3.3.6.tgz",
+            "integrity": "sha512-MB/CnsbaE6reOrnpowJfgkpeSNY0ZuqA6g/k8331a+TP2yIO6X0cUYyEGG8S/k9hFyFCMKlcmmm4pwMrX4sZtQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/switch": {
+            "version": "3.5.0",
+            "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.0.tgz",
+            "integrity": "sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/table": {
+            "version": "3.9.1",
+            "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.9.1.tgz",
+            "integrity": "sha512-3e+Oouw9jGqNDg+JRg7v7fgPqDZd6DtST9S/UPp81f32ntnQ8Wsu7S/J4eyLHu5CVQDqcHkf4xPeeXBgPx4qmw==",
+            "requires": {
+                "@react-types/grid": "^3.2.3",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/tabs": {
+            "version": "3.3.4",
+            "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.4.tgz",
+            "integrity": "sha512-4mCTtFrwMRypyGTZCvNYVT9CkknexO/UYvqwDm2jMYb8JgjRvxnomu776Yh7uyiYKWyql2upm20jqasEOm620w==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/text": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/text/-/text-3.3.6.tgz",
+            "integrity": "sha512-cO3IQ/DQ/xUGGskJ8/zCLkbzvrjlQbRnrJl95BEGs97CmiN+zqGoCqvDhjWEbuPRtfGXJ27CYZDC2oVZetUG4w==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/textfield": {
+            "version": "3.9.0",
+            "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.9.0.tgz",
+            "integrity": "sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/tooltip": {
+            "version": "3.4.6",
+            "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.6.tgz",
+            "integrity": "sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw==",
+            "requires": {
+                "@react-types/overlays": "^3.8.4",
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/view": {
+            "version": "3.4.6",
+            "resolved": "https://registry.npmjs.org/@react-types/view/-/view-3.4.6.tgz",
+            "integrity": "sha512-GAdvvabJAYrVCgOUsZp8KkmNLfkKnDmoMNmwCN9I2OnSS+5JyjTrgNIOiznMjDEqhXTbaefcsVofoUfTYXjtyQ==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
+            }
+        },
+        "@react-types/well": {
+            "version": "3.3.6",
+            "resolved": "https://registry.npmjs.org/@react-types/well/-/well-3.3.6.tgz",
+            "integrity": "sha512-NX4+bMmNYrbjllKR9Xxg0YHNWrscHzZQmcdYiM/Z8qZ1TNVPhXeLmKxCDamlmUSZudCqwui4q5xwzuUyrRRA6w==",
+            "requires": {
+                "@react-types/shared": "^3.22.0"
             }
         },
         "@rkusa/linebreak": {
@@ -5462,6 +7530,23 @@
                 "unicode-trie": "^0.3.0"
             }
         },
+        "@rsuite/icon-font": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/@rsuite/icon-font/-/icon-font-4.0.0.tgz",
+            "integrity": "sha512-rZTgpTH3H3HLczCA2rnkWfoMKm0ZXoRzsrkVujfP/FfslnKUMvO6w56pa8pCvhWGpNEPUsLS2ULnFGpTEcup/Q=="
+        },
+        "@rsuite/icons": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/@rsuite/icons/-/icons-1.0.3.tgz",
+            "integrity": "sha512-qkjYFn1v5YV9eH57Q4AJ8CwsQYfILun2wdoxhQg5+xYxkIu6UyF8vTMmpOzLvcybTE7D8STm4dH7vhpyhPOC7g==",
+            "requires": {
+                "@babel/runtime": "^7.12.1",
+                "@rsuite/icon-font": "^4.0.0",
+                "classnames": "^2.2.5",
+                "insert-css": "^2.0.0",
+                "lodash": "^4.17.20"
+            }
+        },
         "@sigstore/protobuf-specs": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz",
@@ -5488,6 +7573,34 @@
             "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz",
             "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw=="
         },
+        "@spectrum-icons/ui": {
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/@spectrum-icons/ui/-/ui-3.6.2.tgz",
+            "integrity": "sha512-X13fgmi3h0fzolZF+cVJ6NvA91VCb055eBGkhhkQ+vjvUZrHZ8ACD2YUfaDt44BX+fsGUBOZ4fwOrdXnAaVhDQ==",
+            "requires": {
+                "@adobe/react-spectrum-ui": "1.2.0",
+                "@react-spectrum/icon": "^3.7.8",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@spectrum-icons/workflow": {
+            "version": "4.2.7",
+            "resolved": "https://registry.npmjs.org/@spectrum-icons/workflow/-/workflow-4.2.7.tgz",
+            "integrity": "sha512-Qrl2VPDsNd6WyEbqSvcMHPPRKHr6hhFcYXuh26h7XosmIf1irHZqvhpBGEJun2ADao4EQkwMUDy+3VSzvxuGIQ==",
+            "requires": {
+                "@adobe/react-spectrum-workflow": "2.3.4",
+                "@react-spectrum/icon": "^3.7.8",
+                "@swc/helpers": "^0.5.0"
+            }
+        },
+        "@swc/helpers": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.3.tgz",
+            "integrity": "sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==",
+            "requires": {
+                "tslib": "^2.4.0"
+            }
+        },
         "@szmarczak/http-timer": {
             "version": "5.0.1",
             "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz",
@@ -6959,8 +9072,7 @@
         "@types/chai": {
             "version": "4.3.4",
             "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
-            "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
-            "dev": true
+            "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw=="
         },
         "@types/color": {
             "version": "3.0.3",
@@ -7551,8 +9663,7 @@
         "@types/lodash": {
             "version": "4.14.191",
             "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
-            "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
-            "dev": true
+            "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
         },
         "@types/mapbox-gl": {
             "version": "2.7.19",
@@ -7923,25 +10034,16 @@
                 "@types/reactcss": "*"
             }
         },
-        "@types/react-date-range": {
-            "version": "1.4.9",
-            "resolved": "https://registry.npmjs.org/@types/react-date-range/-/react-date-range-1.4.9.tgz",
-            "integrity": "sha512-5oVEDW0ElYmY1+YVSzdMUR8stxSI5QrRJCgCFUvuEAV5197t412vimD9aVTW6g4JTaxCnMmB1BdEOT/odpaBxQ==",
-            "dev": true,
-            "requires": {
-                "@types/react": "*",
-                "date-fns": "^2.16.1"
-            }
-        },
         "@types/react-datepicker": {
-            "version": "3.1.8",
-            "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-3.1.8.tgz",
-            "integrity": "sha512-RFEg7++xhosMq02i2lsuaUPEbZGn66U3dxtvw9LU/ZRqLkBGr9Ft2LTz6vbeYYVtaBdOr0NcQatOLnlfUaS8kw==",
+            "version": "4.19.4",
+            "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-4.19.4.tgz",
+            "integrity": "sha512-HRD0LHTxBVe61LRJgTdPscbapLQl7+jI/7bxnPGpvzdJ/iXN9q7ucYv8HKULeIAN84O5LzFhwTMOkO4QnIUJaQ==",
             "dev": true,
             "requires": {
+                "@popperjs/core": "^2.9.2",
                 "@types/react": "*",
                 "date-fns": "^2.0.1",
-                "popper.js": "^1.14.1"
+                "react-popper": "^2.2.5"
             }
         },
         "@types/react-dom": {
@@ -8044,6 +10146,14 @@
                 "@types/react": "*"
             }
         },
+        "@types/react-window": {
+            "version": "1.8.8",
+            "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
+            "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
+            "requires": {
+                "@types/react": "*"
+            }
+        },
         "@types/reactcss": {
             "version": "1.2.6",
             "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.6.tgz",
@@ -13711,6 +15821,14 @@
                 "@babel/runtime": "^7.1.2"
             }
         },
+        "dom-lib": {
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/dom-lib/-/dom-lib-3.1.6.tgz",
+            "integrity": "sha512-xXEhStHDoAyfhnz8mqDwZ9rnqdqz/9BcrKd1UEw6BlA/l17emFb2dK7q8IX8ArU31pScSU9otEnL6wzvpoT5aw==",
+            "requires": {
+                "@babel/runtime": "^7.20.0"
+            }
+        },
         "dom-serializer": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -18153,6 +20271,11 @@
                 }
             }
         },
+        "insert-css": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
+            "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA=="
+        },
         "inspect-function": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
@@ -18335,6 +20458,17 @@
                 }
             }
         },
+        "intl-messageformat": {
+            "version": "10.5.8",
+            "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.8.tgz",
+            "integrity": "sha512-NRf0jpBWV0vd671G5b06wNofAN8tp7WWDogMZyaU8GUAsmbouyvgwmFJI7zLjfAMpm3zK+vSwRP3jzaoIcMbaA==",
+            "requires": {
+                "@formatjs/ecma402-abstract": "1.18.0",
+                "@formatjs/fast-memoize": "2.2.0",
+                "@formatjs/icu-messageformat-parser": "2.7.3",
+                "tslib": "^2.4.0"
+            }
+        },
         "invariant": {
             "version": "2.2.4",
             "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -26964,11 +29098,6 @@
                 "splaytree": "^3.1.0"
             }
         },
-        "popper.js": {
-            "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",
             "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
@@ -27940,27 +30069,45 @@
                 }
             }
         },
-        "react-date-range": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/react-date-range/-/react-date-range-1.4.0.tgz",
-            "integrity": "sha512-+9t0HyClbCqw1IhYbpWecjsiaftCeRN5cdhsi9v06YdimwyMR2yYHWcgVn3URwtN/txhqKpEZB6UX1fHpvK76w==",
-            "requires": {
-                "classnames": "^2.2.6",
-                "prop-types": "^15.7.2",
-                "react-list": "^0.8.13",
-                "shallow-equal": "^1.2.1"
-            }
-        },
         "react-datepicker": {
-            "version": "3.8.0",
-            "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz",
-            "integrity": "sha512-iFVNEp8DJoX5yEvEiciM7sJKmLGrvE70U38KhpG13XrulNSijeHw1RZkhd/0UmuXR71dcZB/kdfjiidifstZjw==",
+            "version": "4.24.0",
+            "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.24.0.tgz",
+            "integrity": "sha512-2QUC2pP+x4v3Jp06gnFllxKsJR0yoT/K6y86ItxEsveTXUpsx+NBkChWXjU0JsGx/PL8EQnsxN0wHl4zdA1m/g==",
             "requires": {
+                "@popperjs/core": "^2.11.8",
                 "classnames": "^2.2.6",
-                "date-fns": "^2.0.1",
+                "date-fns": "^2.30.0",
                 "prop-types": "^15.7.2",
-                "react-onclickoutside": "^6.10.0",
-                "react-popper": "^1.3.8"
+                "react-onclickoutside": "^6.13.0",
+                "react-popper": "^2.3.0"
+            },
+            "dependencies": {
+                "@babel/runtime": {
+                    "version": "7.23.6",
+                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
+                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+                    "requires": {
+                        "regenerator-runtime": "^0.14.0"
+                    }
+                },
+                "@popperjs/core": {
+                    "version": "2.11.8",
+                    "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+                    "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
+                },
+                "date-fns": {
+                    "version": "2.30.0",
+                    "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+                    "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+                    "requires": {
+                        "@babel/runtime": "^7.21.0"
+                    }
+                },
+                "regenerator-runtime": {
+                    "version": "0.14.1",
+                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+                }
             }
         },
         "react-dock": {
@@ -28030,6 +30177,11 @@
                 }
             }
         },
+        "react-fast-compare": {
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+            "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
+        },
         "react-grid-layout": {
             "version": "1.3.4",
             "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-1.3.4.tgz",
@@ -28133,14 +30285,6 @@
             "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
             "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
         },
-        "react-list": {
-            "version": "0.8.17",
-            "resolved": "https://registry.npmjs.org/react-list/-/react-list-0.8.17.tgz",
-            "integrity": "sha512-pgmzGi0G5uGrdHzMhgO7KR1wx5ZXVvI3SsJUmkblSAKtewIhMwbQiMuQiTE83ozo04BQJbe0r3WIWzSO0dR1xg==",
-            "requires": {
-                "prop-types": "15"
-            }
-        },
         "react-loader-spinner": {
             "version": "5.3.4",
             "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-5.3.4.tgz",
@@ -28250,21 +30394,16 @@
             "integrity": "sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ=="
         },
         "react-onclickoutside": {
-            "version": "6.12.2",
-            "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.2.tgz",
-            "integrity": "sha512-NMXGa223OnsrGVp5dJHkuKxQ4czdLmXSp5jSV9OqiCky9LOpPATn3vLldc+q5fK3gKbEHvr7J1u0yhBh/xYkpA=="
+            "version": "6.13.0",
+            "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.13.0.tgz",
+            "integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A=="
         },
         "react-popper": {
-            "version": "1.3.11",
-            "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz",
-            "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==",
-            "requires": {
-                "@babel/runtime": "^7.1.2",
-                "@hypnosphi/create-react-context": "^0.3.1",
-                "deep-equal": "^1.1.1",
-                "popper.js": "^1.14.4",
-                "prop-types": "^15.6.1",
-                "typed-styles": "^0.0.7",
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
+            "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
+            "requires": {
+                "react-fast-compare": "^3.0.1",
                 "warning": "^4.0.2"
             },
             "dependencies": {
@@ -28472,6 +30611,20 @@
                 }
             }
         },
+        "react-use-set": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/react-use-set/-/react-use-set-1.0.0.tgz",
+            "integrity": "sha512-6BBbOcWc/tOKuwd9gDtdunvOr/g40S0SkCBYvrSJvpI0upzNlHmLoeDvylnoP8PrjQXItClAFxseVGGhEkk7kw=="
+        },
+        "react-window": {
+            "version": "1.8.10",
+            "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
+            "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
+            "requires": {
+                "@babel/runtime": "^7.0.0",
+                "memoize-one": ">=3.1.1 <6"
+            }
+        },
         "reactcss": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
@@ -29283,6 +31436,50 @@
             "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.3.tgz",
             "integrity": "sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q=="
         },
+        "rsuite": {
+            "version": "5.48.0",
+            "resolved": "https://registry.npmjs.org/rsuite/-/rsuite-5.48.0.tgz",
+            "integrity": "sha512-RCqBOU867qErFw/QCJHaA47lwZ7u++/Pk1gpG0YFL3FXxvS3rpo1YDO1QlRyN0WqyZuuANEymbqe6fG21J8+ig==",
+            "requires": {
+                "@babel/runtime": "^7.20.1",
+                "@juggle/resize-observer": "^3.4.0",
+                "@rsuite/icons": "^1.0.2",
+                "@types/chai": "^4.3.3",
+                "@types/lodash": "^4.14.184",
+                "@types/prop-types": "^15.7.5",
+                "@types/react-window": "^1.8.5",
+                "classnames": "^2.3.1",
+                "date-fns": "^2.29.3",
+                "dom-lib": "^3.1.3",
+                "lodash": "^4.17.11",
+                "prop-types": "^15.8.1",
+                "react-use-set": "^1.0.0",
+                "react-window": "^1.8.8",
+                "rsuite-table": "^5.18.2",
+                "schema-typed": "^2.1.3"
+            }
+        },
+        "rsuite-table": {
+            "version": "5.18.2",
+            "resolved": "https://registry.npmjs.org/rsuite-table/-/rsuite-table-5.18.2.tgz",
+            "integrity": "sha512-IelmlHraExYgrkT13WWVENhCywWjBxPkpF2zpsqvMcwzaNAg9lHaVVyajcOKczqGB24NGRE6WgBF5n1RC6XAww==",
+            "requires": {
+                "@babel/runtime": "^7.12.5",
+                "@juggle/resize-observer": "^3.3.1",
+                "@rsuite/icons": "^1.0.0",
+                "classnames": "^2.3.1",
+                "dom-lib": "^3.1.3",
+                "lodash": "^4.17.21",
+                "react-is": "^17.0.2"
+            },
+            "dependencies": {
+                "react-is": {
+                    "version": "17.0.2",
+                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+                    "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+                }
+            }
+        },
         "rtcpeerconnection-shim": {
             "version": "1.2.15",
             "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
@@ -29451,6 +31648,11 @@
                 "object-assign": "^4.1.1"
             }
         },
+        "schema-typed": {
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/schema-typed/-/schema-typed-2.1.3.tgz",
+            "integrity": "sha512-Nk0LLOq0L64HaQsXQGAZ8Z176tDE4jewsxyWe+6QvidNiC33DMaWFg+LaLWJ85uPPBtqBBJlCq9W4c1KEA88WA=="
+        },
         "schema-utils": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
@@ -31827,11 +34029,6 @@
                 "is-typed-array": "^1.1.9"
             }
         },
-        "typed-styles": {
-            "version": "0.0.7",
-            "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
-            "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
-        },
         "typedarray": {
             "version": "0.0.6",
             "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
diff --git a/package.json b/package.json
index 58a25a68c..adaeebf8a 100644
--- a/package.json
+++ b/package.json
@@ -72,8 +72,7 @@
         "@types/react": "^18.0.15",
         "@types/react-autosuggest": "^9.3.14",
         "@types/react-color": "^2.17.6",
-        "@types/react-date-range": "^1.4.9",
-        "@types/react-datepicker": "^3.1.8",
+        "@types/react-datepicker": "^4.19.4",
         "@types/react-dom": "^18.0.6",
         "@types/react-grid-layout": "^1.3.2",
         "@types/react-icons": "^3.0.0",
@@ -132,6 +131,7 @@
         "webpack-hot-middleware": "^2.25.1"
     },
     "dependencies": {
+        "@adobe/react-spectrum": "^3.32.2",
         "@azure/storage-blob": "^12.14.0",
         "@emotion/react": "^11.11.0",
         "@emotion/styled": "^11.11.0",
@@ -149,8 +149,6 @@
         "@material-ui/core": "^4.12.3",
         "@mui/icons-material": "^5.11.16",
         "@mui/material": "^5.13.1",
-        "@mui/x-date-pickers": "^6.18.5",
-        "@mui/x-date-pickers-pro": "^6.18.5",
         "@octokit/core": "^4.0.4",
         "@react-google-maps/api": "^2.7.0",
         "@react-three/fiber": "^6.2.3",
@@ -300,8 +298,7 @@
         "react-chartjs-2": "^4.3.0",
         "react-color": "^2.19.3",
         "react-compound-slider": "^2.5.0",
-        "react-date-range": "^1.4.0",
-        "react-datepicker": "^3.8.0",
+        "react-datepicker": "^4.24.0",
         "react-dom": "^18.2.0",
         "react-dropzone": "^14.2.3",
         "react-grid-layout": "^1.3.4",
@@ -328,6 +325,7 @@
         "request-promise": "^4.2.6",
         "reveal.js": "^4.3.0",
         "rimraf": "^3.0.0",
+        "rsuite": "^5.48.0",
         "serializr": "^1.5.4",
         "sharp": "^0.23.4",
         "shelljs": "^0.8.5",
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 306e9e14b..5b9f71641 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -38,6 +38,7 @@ export enum DocumentType {
     GROUP = 'group',
     PUSHPIN = 'pushpin',
     MAPROUTE = 'maproute',
+    CALENDAR = 'calendar',
 
     SCRIPTDB = 'scriptdb', // database of scripts
     GROUPDB = 'groupdb', // database of groups
@@ -62,4 +63,5 @@ export enum CollectionViewType {
     Pile = 'pileup',
     StackedTimeline = 'stacked timeline',
     NoteTaking = 'notetaking',
+    Calendar = 'calendar_view'
 }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index f5f140ae9..778dbe5b8 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -186,6 +186,8 @@ export class DocumentOptions {
     map_bearing?: NUMt = new NumInfo('bearing of a map view', false);
     map_style?: STRt = new StrInfo('mapbox style for a map view', false);
 
+    date_range?: STRt = new StrInfo('date range for calendar', false);
+
     wikiData?: STRt = new StrInfo('WikiData ID related to map location');
     description?: STRt = new StrInfo('A description of the document');
     _timecodeToShow?: NUMt = new NumInfo('the time that a document should be displayed (e.g., when an annotation shows up as a video plays)', false);
@@ -1039,6 +1041,7 @@ export namespace Docs {
         export function LoadingDocument(file: File | string, options: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.LOADING), undefined, { _height: 150, _width: 200, title: typeof file == 'string' ? file : file.name, ...options }, undefined, '');
         }
+ 
 
         export function RTFDocument(field: RichTextField, options: DocumentOptions = {}, fieldKey: string = 'text') {
             return InstanceFromProto(Prototypes.get(DocumentType.RTF), field, options, undefined, fieldKey);
@@ -1160,6 +1163,10 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), { infoWindowOpen, ...options }, id);
         }
 
+        export function CalendarDocument(options: DocumentOptions={}, documents: Array<Doc>){
+            return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), options)
+        }
+
         // shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView)
         // export function KVPDocument(document: Doc, options: DocumentOptions = {}) {
         //     return InstanceFromProto(Prototypes.get(DocumentType.KVP), document, { title: document.title + '.kvp', ...options });
@@ -1214,6 +1221,10 @@ export namespace Docs {
             return doc;
         }
 
+        export function CalendarCollectionDocument(documents: Array<Doc>, options: DocumentOptions){
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), {...options,  _type_collection: CollectionViewType.Calendar});
+        }
+
         export function StackingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _type_collection: CollectionViewType.Stacking }, id, undefined, protoId);
         }
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 39ba41652..e471db7c6 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
 import './CalendarManager.scss';
 import { observer } from "mobx-react";
 import { action, computed, observable, runInAction } from 'mobx';
-import { Doc } from '../../fields/Doc';
+import { Doc, DocListCast } from '../../fields/Doc';
 import { DocumentView } from '../views/nodes/DocumentView';
 import { DictationOverlay } from '../views/DictationOverlay';
 import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
@@ -10,19 +10,38 @@ import { MainViewModal } from '../views/MainViewModal';
 import { TextField } from '@material-ui/core';
 import Select from 'react-select';
 import { SettingsManager } from './SettingsManager';
-import { StrCast } from '../../fields/Types';
+import { DocCast, StrCast } from '../../fields/Types';
 import { SelectionManager } from './SelectionManager';
 import { DocumentManager } from './DocumentManager';
 import { DocData } from '../../fields/DocSymbols';
-import { DateRange, Range, RangeKeyDict } from 'react-date-range';
+// import { DateRange, Range, RangeKeyDict } from 'react-date-range';
 import { Button } from 'browndash-components';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import {DateRangePicker} from '@adobe/react-spectrum';
 import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
-import 'react-date-range/dist/styles.css';
-import 'react-date-range/dist/theme/default.css';
+import { Docs } from '../documents/Documents';
+// import 'react-date-range/dist/styles.css';
+// import 'react-date-range/dist/theme/default.css';
 
 type CreationType = 'new-calendar' | 'existing-calendar' | 'manage-calendars';
 
+interface CalendarSelectOptions {
+    label: string,
+    value: string
+}
+
+const formatDateToString = (date: Date) => {
+    const year = date.getFullYear();
+    const month = String(date.getMonth() + 1).padStart(2, '0'); 
+    const day = String(date.getDate()).padStart(2, '0');
+
+    return `${year}-${month}-${day}`;
+}
+
+// TODO: If doc is already part of a calendar, display that
+// TODO: For a doc already in a calendar: give option to edit date range, delete from calendar
+
+
 @observer
 export class CalendarManager extends React.Component<{}> {
     public static Instance: CalendarManager;
@@ -36,11 +55,28 @@ export class CalendarManager extends React.Component<{}> {
 
     @observable private creationType: CreationType = 'new-calendar';
 
+    @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars.data);
+
+    @computed get selectOptions() {
+        return this.existingCalendars.map(calendar => ({ label: StrCast(calendar.title), value: StrCast(calendar.title) }));
+    }
+
+    @observable 
+    selectedExistingCalendarOption: CalendarSelectOptions | null = null;
+
     @observable 
     calendarName: string = "";
 
+    @observable 
+    calendarDescription: string = "";
+
+    @observable
+    errorMessage: string = "";
+
     @action
     setInterationType = (type: CreationType) => {
+        this.errorMessage = "";
+        this.calendarName = "";
         this.creationType = type;
     }
 
@@ -76,6 +112,60 @@ export class CalendarManager extends React.Component<{}> {
         
     }
 
+    @action
+    handleSelectChange = (option: any) => {
+        let selectOpt = option as CalendarSelectOptions;
+        this.selectedExistingCalendarOption = selectOpt;
+        this.calendarName = selectOpt.value; // or label
+    }
+
+    @action
+    handleTextFieldChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+        this.calendarName = event.target.value;
+    }
+
+    // TODO: Make undoable
+    private addToCalendar = () => {
+        let docs = SelectionManager.Views().length < 2 ? [this.targetDoc] : SelectionManager.Views().map(docView => docView.rootDoc);
+        const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar
+
+        if (targetDoc) {
+            let calendar: Doc;
+            if (this.creationType === 'new-calendar'){
+                if (!this.existingCalendars.find(doc => StrCast(doc.title) === this.calendarName)){ 
+                    calendar = Docs.Create.CalendarDocument({
+                        title: this.calendarName,
+                        description: this.calendarDescription
+                    }, []);
+                } else {
+                    this.errorMessage = "Calendar with this name already exists"
+                    return;
+                }
+            } else {
+                // find existing calendar based on selected name (should technically always find one)
+                const existingCalendar = this.existingCalendars.find(calendar => StrCast(calendar.title) === this.calendarName);
+                if (existingCalendar) calendar = existingCalendar;
+                else {
+                    this.errorMessage = "Must select an existing calendar";
+                    return;
+                }
+            }
+            // Get start and end date strings
+            const startDateStr = formatDateToString(this.selectedDateRange.start);
+            const endDateStr = formatDateToString(this.selectedDateRange.end);
+
+            const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding 
+            subDocEmbedding.embedContainer = calendar; // set embed container
+            subDocEmbedding.date_range = `${startDateStr}-${endDateStr}`; // set subDoc date range
+
+            Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar
+            
+            Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to dashboard calendars
+            
+        }
+
+    }
+
     private focusOn = (contents: string) => {
         const title = this.targetDoc ? StrCast(this.targetDoc.title) : '';
         const docs = SelectionManager.Views().length > 1 ? SelectionManager.Views().map(docView => docView.props.Document) : [this.targetDoc];
@@ -108,20 +198,19 @@ export class CalendarManager extends React.Component<{}> {
     };
 
     @observable
-    selectedDateRange: Range[] = [{
-        startDate: new Date(),
-        endDate: undefined,
-        key: 'selection'
+    selectedDateRange: any = [{
+        start: new Date(),
+        end: new Date(),
     }]
 
     @action
-    setSelectedDateRange = (range: Range[]) => {
+    setSelectedDateRange = (range: any) => {
         this.selectedDateRange = range;
     }
 
     @computed
     get createButtonActive() {
-        if (this.calendarName.length === 0) return false // disabled if no calendar name
+        if (this.calendarName.length === 0 || this.errorMessage.length > 0) return false // disabled if no calendar name
         let startDate: Date | undefined;
         let endDate: Date | undefined;
         try {
@@ -170,6 +259,7 @@ export class CalendarManager extends React.Component<{}> {
                     {this.creationType === 'new-calendar' ? 
                         <TextField
                             fullWidth
+                            onChange={this.handleTextFieldChange}
                             placeholder='Enter calendar name...'
                             variant='filled'
                             style={{
@@ -178,38 +268,55 @@ export class CalendarManager extends React.Component<{}> {
                                 borderRadius: '5px'
 
                             }}
-                            
                         />
                     :
                         <Select
                             className='existing-calendar-search'
                             placeholder='Search for existing calendar...'
-                            isMulti
+                            isClearable
                             isSearchable
+                            options={this.selectOptions}
+                            value={this.selectedExistingCalendarOption}
+                            onChange={this.handleSelectChange}
+                            styles={{
+                                control: () => ({
+                                    display: 'inline-flex',
+                                    width: '100%',
+                                }),
+                                indicatorSeparator: () => ({
+                                    display: 'inline-flex',
+                                    visibility: 'hidden',
+                                }),
+                                indicatorsContainer: () => ({
+                                    display: 'inline-flex',
+                                    textDecorationColor: 'black',
+                                }),
+                                valueContainer: () => ({
+                                    display: 'inline-flex',
+                                    fontStyle: StrCast(Doc.UserDoc().userColor),
+                                    color: StrCast(Doc.UserDoc().userColor),
+                                    width: '100%',
+                                }),
+                            }}
                         >
-                            
                         </Select>
                     }
                 </div>
                 <div className='date-range-picker-container'>
-                    <DateRange
-                        className='react-date-range'
-                        editableDateInputs={true}
-                        // ranges={[selectionRange]}
-                        onChange={item => this.setSelectedDateRange([item.selection])}
-                        ranges={this.selectedDateRange}
-                    // onChange={this.handleSelect}
-                    />
+                    <DateRangePicker 
+                        value={this.selectedDateRange}
+                        onChange={(v => this.setSelectedDateRange(v))}
+                        label="Date range" />
                 </div>
                 <div className='create-button-container'>
                     <Button
                         active={this.createButtonActive}
+                        onClick={() => {}}
                         text="Add to Calendar"
                         iconPlacement='right'
                         icon={<FontAwesomeIcon icon={faPlus as IconLookup}/>}
                     />
                 </div>
-                
             </div>
         )
     }
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index 2765e95e6..3c8221f6a 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -379,13 +379,42 @@ export class DashboardView extends React.Component {
         Doc.AddDocToList(Doc.MyDashboards, 'data', dashboardDoc);
 
         DashboardView.SetupDashboardTrails(dashboardDoc);
-
+        DashboardView.SetupDashboardCalendars(dashboardDoc);
         // open this new dashboard
         Doc.ActiveDashboard = dashboardDoc;
         Doc.ActivePage = 'dashboard';
         Doc.ActivePresentation = undefined;
     };
 
+    public static SetupDashboardCalendars(dashboardDoc: Doc){
+        // this section is creating the button document itself  ===  myTrails = new Button
+        
+        //  create a a list of calendars (as a CalendarCollectionDocument) and store it on the new dashboard
+        const reqdOpts: DocumentOptions = {
+            title: 'My Calendars',
+            _layout_showTitle: 'title',
+            _height: 100,
+            treeView_HideTitle: true,
+            _layout_fitWidth: true,
+            _gridGap: 5,
+            _forceActive: true,
+            childDragAction: 'embed',
+            treeView_TruncateTitleWidth: 150,
+            ignoreClick: true,
+            contextMenuIcons: new List<string>(['plus']),
+            contextMenuLabels: new List<string>(['Create New Calendar']),
+            _lockedPosition: true,
+            layout_boxShadow: '0 0',
+            childDontRegisterViews: true,
+            dropAction: 'same',
+            isSystem: true,
+            layout_explainer: 'All of the calendars that you have created will appear here.',
+        };
+        const myCalendars = DocUtils.AssignScripts(Docs.Create.CalendarCollectionDocument([], reqdOpts));
+        // { treeView_ChildDoubleClick: 'openPresentation(documentView.rootDoc)' }
+        dashboardDoc.myCalendars = new PrefetchProxy(myCalendars);
+    }
+
     public static SetupDashboardTrails(dashboardDoc: Doc) {
         // this section is creating the button document itself  ===  myTrails = new Button
         const reqdBtnOpts: DocumentOptions = {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 2e8047309..f479b9b11 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -465,6 +465,7 @@ export class CollectionDockingView extends CollectionSubView() {
         });
         const copy = Docs.Create.DockDocument(newtabs, json, { title: incrementTitleCopy(StrCast(doc.title)) });
         DashboardView.SetupDashboardTrails(copy);
+        DashboardView.SetupDashboardCalendars(copy); // Zaul TODO: needed?
         return DashboardView.openDashboard(copy);
     }
 
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 1678d9012..cfbef2d21 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -147,6 +147,7 @@ export class Doc extends RefField {
     public static get MyTopBarBtns()          { return DocCast(Doc.UserDoc().myTopBarBtns); } // prettier-ignore
     public static get MyRecentlyClosed()      { return DocCast(Doc.UserDoc().myRecentlyClosed); } // prettier-ignore
     public static get MyTrails()              { return DocCast(Doc.ActiveDashboard?.myTrails); } // prettier-ignore
+    public static get MyCalendars()           { return DocCast(Doc.ActiveDashboard?.myCalendars); } // prettier-ignore
     public static get MyOverlayDocs()         { return DocListCast(Doc.ActiveDashboard?.myOverlayDocs ?? DocCast(Doc.UserDoc().myOverlayDocs)?.data); } // prettier-ignore
     public static get MyPublishedDocs()       { return DocListCast(Doc.ActiveDashboard?.myPublishedDocs ?? DocCast(Doc.UserDoc().myPublishedDocs)?.data); } // prettier-ignore
     public static get MyDashboards()          { return DocCast(Doc.UserDoc().myDashboards); } // prettier-ignore
-- 
cgit v1.2.3-70-g09d2


From 8ed319d624e7b94fd8ead3b39e9d95f34ed62eae Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sat, 16 Dec 2023 17:57:50 -0500
Subject: trying to fix package.json inconsistency with previous push

---
 package-lock.json                   | 274 ++++++++++--------------------------
 package.json                        |   5 +-
 src/client/util/CalendarManager.tsx |   5 +-
 3 files changed, 80 insertions(+), 204 deletions(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/package-lock.json b/package-lock.json
index 29ab1ff66..5254adf23 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3152,6 +3152,25 @@
             "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
             "dev": true
         },
+        "@hypnosphi/create-react-context": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz",
+            "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==",
+            "requires": {
+                "gud": "^1.0.0",
+                "warning": "^4.0.3"
+            },
+            "dependencies": {
+                "warning": {
+                    "version": "4.0.3",
+                    "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
+                    "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
+                    "requires": {
+                        "loose-envify": "^1.0.0"
+                    }
+                }
+            }
+        },
         "@icons/material": {
             "version": "0.2.4",
             "resolved": "https://registry.npmjs.org/@icons/material/-/material-0.2.4.tgz",
@@ -3296,11 +3315,6 @@
                 "@jridgewell/sourcemap-codec": "1.4.14"
             }
         },
-        "@juggle/resize-observer": {
-            "version": "3.4.0",
-            "resolved": "https://registry.npmjs.org/@juggle/resize-observer/-/resize-observer-3.4.0.tgz",
-            "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA=="
-        },
         "@log4js-node/log4js-api": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/@log4js-node/log4js-api/-/log4js-api-1.0.2.tgz",
@@ -7530,23 +7544,6 @@
                 "unicode-trie": "^0.3.0"
             }
         },
-        "@rsuite/icon-font": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/@rsuite/icon-font/-/icon-font-4.0.0.tgz",
-            "integrity": "sha512-rZTgpTH3H3HLczCA2rnkWfoMKm0ZXoRzsrkVujfP/FfslnKUMvO6w56pa8pCvhWGpNEPUsLS2ULnFGpTEcup/Q=="
-        },
-        "@rsuite/icons": {
-            "version": "1.0.3",
-            "resolved": "https://registry.npmjs.org/@rsuite/icons/-/icons-1.0.3.tgz",
-            "integrity": "sha512-qkjYFn1v5YV9eH57Q4AJ8CwsQYfILun2wdoxhQg5+xYxkIu6UyF8vTMmpOzLvcybTE7D8STm4dH7vhpyhPOC7g==",
-            "requires": {
-                "@babel/runtime": "^7.12.1",
-                "@rsuite/icon-font": "^4.0.0",
-                "classnames": "^2.2.5",
-                "insert-css": "^2.0.0",
-                "lodash": "^4.17.20"
-            }
-        },
         "@sigstore/protobuf-specs": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz",
@@ -9072,7 +9069,8 @@
         "@types/chai": {
             "version": "4.3.4",
             "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.4.tgz",
-            "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw=="
+            "integrity": "sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw==",
+            "dev": true
         },
         "@types/color": {
             "version": "3.0.3",
@@ -9663,7 +9661,8 @@
         "@types/lodash": {
             "version": "4.14.191",
             "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.191.tgz",
-            "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+            "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ==",
+            "dev": true
         },
         "@types/mapbox-gl": {
             "version": "2.7.19",
@@ -10035,15 +10034,14 @@
             }
         },
         "@types/react-datepicker": {
-            "version": "4.19.4",
-            "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-4.19.4.tgz",
-            "integrity": "sha512-HRD0LHTxBVe61LRJgTdPscbapLQl7+jI/7bxnPGpvzdJ/iXN9q7ucYv8HKULeIAN84O5LzFhwTMOkO4QnIUJaQ==",
+            "version": "3.1.8",
+            "resolved": "https://registry.npmjs.org/@types/react-datepicker/-/react-datepicker-3.1.8.tgz",
+            "integrity": "sha512-RFEg7++xhosMq02i2lsuaUPEbZGn66U3dxtvw9LU/ZRqLkBGr9Ft2LTz6vbeYYVtaBdOr0NcQatOLnlfUaS8kw==",
             "dev": true,
             "requires": {
-                "@popperjs/core": "^2.9.2",
                 "@types/react": "*",
                 "date-fns": "^2.0.1",
-                "react-popper": "^2.2.5"
+                "popper.js": "^1.14.1"
             }
         },
         "@types/react-dom": {
@@ -10146,14 +10144,6 @@
                 "@types/react": "*"
             }
         },
-        "@types/react-window": {
-            "version": "1.8.8",
-            "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.8.tgz",
-            "integrity": "sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q==",
-            "requires": {
-                "@types/react": "*"
-            }
-        },
         "@types/reactcss": {
             "version": "1.2.6",
             "resolved": "https://registry.npmjs.org/@types/reactcss/-/reactcss-1.2.6.tgz",
@@ -14843,16 +14833,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.5",
             "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
@@ -15182,9 +15162,27 @@
             }
         },
         "date-fns": {
-            "version": "2.29.3",
-            "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
-            "integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
+            "version": "2.30.0",
+            "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+            "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+            "requires": {
+                "@babel/runtime": "^7.21.0"
+            },
+            "dependencies": {
+                "@babel/runtime": {
+                    "version": "7.23.6",
+                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
+                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+                    "requires": {
+                        "regenerator-runtime": "^0.14.0"
+                    }
+                },
+                "regenerator-runtime": {
+                    "version": "0.14.1",
+                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+                }
+            }
         },
         "dayjs": {
             "version": "1.11.10",
@@ -15821,14 +15819,6 @@
                 "@babel/runtime": "^7.1.2"
             }
         },
-        "dom-lib": {
-            "version": "3.1.6",
-            "resolved": "https://registry.npmjs.org/dom-lib/-/dom-lib-3.1.6.tgz",
-            "integrity": "sha512-xXEhStHDoAyfhnz8mqDwZ9rnqdqz/9BcrKd1UEw6BlA/l17emFb2dK7q8IX8ArU31pScSU9otEnL6wzvpoT5aw==",
-            "requires": {
-                "@babel/runtime": "^7.20.0"
-            }
-        },
         "dom-serializer": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -16293,28 +16283,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",
@@ -16326,7 +16294,6 @@
             "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
             "dev": true,
             "requires": {
-                "d": "^1.0.1",
                 "ext": "^1.1.2"
             }
         },
@@ -20271,11 +20238,6 @@
                 }
             }
         },
-        "insert-css": {
-            "version": "2.0.0",
-            "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
-            "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA=="
-        },
         "inspect-function": {
             "version": "0.2.2",
             "resolved": "https://registry.npmjs.org/inspect-function/-/inspect-function-0.2.2.tgz",
@@ -29098,6 +29060,11 @@
                 "splaytree": "^3.1.0"
             }
         },
+        "popper.js": {
+            "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",
             "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz",
@@ -30070,44 +30037,15 @@
             }
         },
         "react-datepicker": {
-            "version": "4.24.0",
-            "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-4.24.0.tgz",
-            "integrity": "sha512-2QUC2pP+x4v3Jp06gnFllxKsJR0yoT/K6y86ItxEsveTXUpsx+NBkChWXjU0JsGx/PL8EQnsxN0wHl4zdA1m/g==",
+            "version": "3.8.0",
+            "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz",
+            "integrity": "sha512-iFVNEp8DJoX5yEvEiciM7sJKmLGrvE70U38KhpG13XrulNSijeHw1RZkhd/0UmuXR71dcZB/kdfjiidifstZjw==",
             "requires": {
-                "@popperjs/core": "^2.11.8",
                 "classnames": "^2.2.6",
-                "date-fns": "^2.30.0",
+                "date-fns": "^2.0.1",
                 "prop-types": "^15.7.2",
-                "react-onclickoutside": "^6.13.0",
-                "react-popper": "^2.3.0"
-            },
-            "dependencies": {
-                "@babel/runtime": {
-                    "version": "7.23.6",
-                    "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz",
-                    "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
-                    "requires": {
-                        "regenerator-runtime": "^0.14.0"
-                    }
-                },
-                "@popperjs/core": {
-                    "version": "2.11.8",
-                    "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
-                    "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A=="
-                },
-                "date-fns": {
-                    "version": "2.30.0",
-                    "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
-                    "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
-                    "requires": {
-                        "@babel/runtime": "^7.21.0"
-                    }
-                },
-                "regenerator-runtime": {
-                    "version": "0.14.1",
-                    "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
-                    "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
-                }
+                "react-onclickoutside": "^6.10.0",
+                "react-popper": "^1.3.8"
             }
         },
         "react-dock": {
@@ -30177,11 +30115,6 @@
                 }
             }
         },
-        "react-fast-compare": {
-            "version": "3.2.2",
-            "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
-            "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
-        },
         "react-grid-layout": {
             "version": "1.3.4",
             "resolved": "https://registry.npmjs.org/react-grid-layout/-/react-grid-layout-1.3.4.tgz",
@@ -30399,11 +30332,16 @@
             "integrity": "sha512-ty8So6tcUpIb+ZE+1HAhbLROvAIJYyJe/1vRrrcmW+jLsaM+/powDRqxzo6hSh9CuRZGSL1Q8mvcF5WRD93a0A=="
         },
         "react-popper": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.3.0.tgz",
-            "integrity": "sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==",
-            "requires": {
-                "react-fast-compare": "^3.0.1",
+            "version": "1.3.11",
+            "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz",
+            "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==",
+            "requires": {
+                "@babel/runtime": "^7.1.2",
+                "@hypnosphi/create-react-context": "^0.3.1",
+                "deep-equal": "^1.1.1",
+                "popper.js": "^1.14.4",
+                "prop-types": "^15.6.1",
+                "typed-styles": "^0.0.7",
                 "warning": "^4.0.2"
             },
             "dependencies": {
@@ -30611,20 +30549,6 @@
                 }
             }
         },
-        "react-use-set": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/react-use-set/-/react-use-set-1.0.0.tgz",
-            "integrity": "sha512-6BBbOcWc/tOKuwd9gDtdunvOr/g40S0SkCBYvrSJvpI0upzNlHmLoeDvylnoP8PrjQXItClAFxseVGGhEkk7kw=="
-        },
-        "react-window": {
-            "version": "1.8.10",
-            "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.10.tgz",
-            "integrity": "sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg==",
-            "requires": {
-                "@babel/runtime": "^7.0.0",
-                "memoize-one": ">=3.1.1 <6"
-            }
-        },
         "reactcss": {
             "version": "1.2.3",
             "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
@@ -31436,50 +31360,6 @@
             "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.3.tgz",
             "integrity": "sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q=="
         },
-        "rsuite": {
-            "version": "5.48.0",
-            "resolved": "https://registry.npmjs.org/rsuite/-/rsuite-5.48.0.tgz",
-            "integrity": "sha512-RCqBOU867qErFw/QCJHaA47lwZ7u++/Pk1gpG0YFL3FXxvS3rpo1YDO1QlRyN0WqyZuuANEymbqe6fG21J8+ig==",
-            "requires": {
-                "@babel/runtime": "^7.20.1",
-                "@juggle/resize-observer": "^3.4.0",
-                "@rsuite/icons": "^1.0.2",
-                "@types/chai": "^4.3.3",
-                "@types/lodash": "^4.14.184",
-                "@types/prop-types": "^15.7.5",
-                "@types/react-window": "^1.8.5",
-                "classnames": "^2.3.1",
-                "date-fns": "^2.29.3",
-                "dom-lib": "^3.1.3",
-                "lodash": "^4.17.11",
-                "prop-types": "^15.8.1",
-                "react-use-set": "^1.0.0",
-                "react-window": "^1.8.8",
-                "rsuite-table": "^5.18.2",
-                "schema-typed": "^2.1.3"
-            }
-        },
-        "rsuite-table": {
-            "version": "5.18.2",
-            "resolved": "https://registry.npmjs.org/rsuite-table/-/rsuite-table-5.18.2.tgz",
-            "integrity": "sha512-IelmlHraExYgrkT13WWVENhCywWjBxPkpF2zpsqvMcwzaNAg9lHaVVyajcOKczqGB24NGRE6WgBF5n1RC6XAww==",
-            "requires": {
-                "@babel/runtime": "^7.12.5",
-                "@juggle/resize-observer": "^3.3.1",
-                "@rsuite/icons": "^1.0.0",
-                "classnames": "^2.3.1",
-                "dom-lib": "^3.1.3",
-                "lodash": "^4.17.21",
-                "react-is": "^17.0.2"
-            },
-            "dependencies": {
-                "react-is": {
-                    "version": "17.0.2",
-                    "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
-                    "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
-                }
-            }
-        },
         "rtcpeerconnection-shim": {
             "version": "1.2.15",
             "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
@@ -31648,11 +31528,6 @@
                 "object-assign": "^4.1.1"
             }
         },
-        "schema-typed": {
-            "version": "2.1.3",
-            "resolved": "https://registry.npmjs.org/schema-typed/-/schema-typed-2.1.3.tgz",
-            "integrity": "sha512-Nk0LLOq0L64HaQsXQGAZ8Z176tDE4jewsxyWe+6QvidNiC33DMaWFg+LaLWJ85uPPBtqBBJlCq9W4c1KEA88WA=="
-        },
         "schema-utils": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
@@ -33984,12 +33859,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",
@@ -34029,6 +33898,11 @@
                 "is-typed-array": "^1.1.9"
             }
         },
+        "typed-styles": {
+            "version": "0.0.7",
+            "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
+            "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
+        },
         "typedarray": {
             "version": "0.0.6",
             "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
diff --git a/package.json b/package.json
index adaeebf8a..f7936b108 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
         "@types/react": "^18.0.15",
         "@types/react-autosuggest": "^9.3.14",
         "@types/react-color": "^2.17.6",
-        "@types/react-datepicker": "^4.19.4",
+        "@types/react-datepicker": "^3.1.8",
         "@types/react-dom": "^18.0.6",
         "@types/react-grid-layout": "^1.3.2",
         "@types/react-icons": "^3.0.0",
@@ -298,7 +298,7 @@
         "react-chartjs-2": "^4.3.0",
         "react-color": "^2.19.3",
         "react-compound-slider": "^2.5.0",
-        "react-datepicker": "^4.24.0",
+        "react-datepicker": "^3.8.0",
         "react-dom": "^18.2.0",
         "react-dropzone": "^14.2.3",
         "react-grid-layout": "^1.3.4",
@@ -325,7 +325,6 @@
         "request-promise": "^4.2.6",
         "reveal.js": "^4.3.0",
         "rimraf": "^3.0.0",
-        "rsuite": "^5.48.0",
         "serializr": "^1.5.4",
         "sharp": "^0.23.4",
         "shelljs": "^0.8.5",
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index e471db7c6..15c811e91 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -160,7 +160,10 @@ export class CalendarManager extends React.Component<{}> {
 
             Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar
             
-            Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to dashboard calendars
+            if (this.creationType === 'new-calendar'){
+                Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
+            }
+            
             
         }
 
-- 
cgit v1.2.3-70-g09d2


From dd467ca443c9c55ea9e570a0bdd2a4b7329965a2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sat, 16 Dec 2023 19:25:42 -0500
Subject: another fix to calendar

---
 src/client/util/CalendarManager.tsx | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 50a5437a0..3872294db 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -17,6 +17,8 @@ import { DocData } from '../../fields/DocSymbols';
 // import { DateRange, Range, RangeKeyDict } from 'react-date-range';
 import { Button } from 'browndash-components';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Provider, useProvider, defaultTheme } from '@adobe/react-spectrum';
+
 import { DateRangePicker } from '@adobe/react-spectrum';
 import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
 import { Docs } from '../documents/Documents';
@@ -297,7 +299,9 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                     )}
                 </div>
                 <div className="date-range-picker-container">
-                    <DateRangePicker value={this.selectedDateRange} onChange={v => this.setSelectedDateRange(v)} label="Date range" />
+                    <Provider theme={defaultTheme}>
+                        <DateRangePicker value={this.selectedDateRange} onChange={v => this.setSelectedDateRange(v)} label="Date range" />
+                    </Provider>
                 </div>
                 <div className="create-button-container">
                     <Button active={this.createButtonActive} onClick={() => {}} text="Add to Calendar" iconPlacement="right" icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
-- 
cgit v1.2.3-70-g09d2


From e39665be22ecee11b093db07ebe72896a6d43a8c Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sun, 17 Dec 2023 15:59:39 -0500
Subject: starting calendar collection view

---
 package-lock.json                                  |  2 +
 package.json                                       |  4 +-
 src/client/documents/DocumentTypes.ts              |  2 +-
 src/client/documents/Documents.ts                  | 12 +++-
 src/client/util/CalendarManager.scss               | 18 ++---
 src/client/util/CalendarManager.tsx                | 82 +++++++++++++++++-----
 src/client/util/CurrentUserUtils.ts                |  2 +-
 .../views/collections/CollectionCalendarView.tsx   | 32 +++++++++
 src/client/views/collections/CollectionView.tsx    |  3 +
 src/client/views/nodes/DocumentContentsView.tsx    |  2 +
 src/client/views/nodes/MapBox/MapBox.tsx           | 18 +++--
 src/client/views/nodes/calendarBox/CalendarBox.tsx | 26 +++++++
 12 files changed, 162 insertions(+), 41 deletions(-)
 create mode 100644 src/client/views/collections/CollectionCalendarView.tsx
 create mode 100644 src/client/views/nodes/calendarBox/CalendarBox.tsx

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/package-lock.json b/package-lock.json
index 180ff097a..2d2740381 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
                 "@fortawesome/free-regular-svg-icons": "^6.5.1",
                 "@fortawesome/free-solid-svg-icons": "^6.5.1",
                 "@fortawesome/react-fontawesome": "^0.2.0",
+                "@internationalized/date": "^3.5.0",
                 "@mapbox/mapbox-gl-geocoder": "^5.0.2",
                 "@mui/icons-material": "^5.14.19",
                 "@mui/material": "^5.14.19",
@@ -37,6 +38,7 @@
                 "@types/dom-speech-recognition": "0.0.4",
                 "@types/formidable": "3.4.5",
                 "@types/google-maps": "^3.2.6",
+                "@types/mapbox-gl": "^2.7.19",
                 "@types/reveal": "^4.2.0",
                 "@types/supercluster": "^7.1.3",
                 "@types/web": "^0.0.127",
diff --git a/package.json b/package.json
index 661f8c5ec..098e30ffb 100644
--- a/package.json
+++ b/package.json
@@ -92,12 +92,12 @@
         "webpack-hot-middleware": "^2.25.4"
     },
     "dependencies": {
+        "@adobe/react-spectrum": "^3.32.2",
         "@azure/storage-blob": "^12.17.0",
         "@babel/preset-env": "^7.23.5",
         "@babel/preset-react": "^7.23.3",
         "@bundled-es-modules/pdfjs-dist": "^3.6.172-alpha.1",
         "@emotion/react": "^11.11.1",
-        "@adobe/react-spectrum": "^3.32.2",
         "@emotion/styled": "^11.11.0",
         "@ffmpeg/core": "0.12.4",
         "@ffmpeg/ffmpeg": "0.12.7",
@@ -106,6 +106,7 @@
         "@fortawesome/free-regular-svg-icons": "^6.5.1",
         "@fortawesome/free-solid-svg-icons": "^6.5.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
+        "@internationalized/date": "^3.5.0",
         "@mapbox/mapbox-gl-geocoder": "^5.0.2",
         "@mui/icons-material": "^5.14.19",
         "@mui/material": "^5.14.19",
@@ -121,6 +122,7 @@
         "@types/dom-speech-recognition": "0.0.4",
         "@types/formidable": "3.4.5",
         "@types/google-maps": "^3.2.6",
+        "@types/mapbox-gl": "^2.7.19",
         "@types/reveal": "^4.2.0",
         "@types/supercluster": "^7.1.3",
         "@types/web": "^0.0.127",
diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts
index 5c2792a53..1123bcac9 100644
--- a/src/client/documents/DocumentTypes.ts
+++ b/src/client/documents/DocumentTypes.ts
@@ -62,5 +62,5 @@ export enum CollectionViewType {
     Pile = 'pileup',
     StackedTimeline = 'stacked timeline',
     NoteTaking = 'notetaking',
-    Calendar = 'calendar_view'
+    Calendar = 'calendar'
 }
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index d6fd8aea3..ff14eb101 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -58,6 +58,7 @@ import { VideoBox } from '../views/nodes/VideoBox';
 import { WebBox } from '../views/nodes/WebBox';
 import { SearchBox } from '../views/search/SearchBox';
 import { CollectionViewType, DocumentType } from './DocumentTypes';
+import { CalendarBox } from '../views/nodes/calendarBox/CalendarBox';
 const {
     default: { DFLT_IMAGE_NATIVE_DIM },
 } = require('../views/global/globalCssVariables.module.scss');
@@ -784,6 +785,13 @@ export namespace Docs {
                     options: {},
                 },
             ],
+            [
+                DocumentType.CALENDAR,
+                {
+                    layout: { view: CalendarBox, dataField: defaultDataKey },
+                    options: {},
+                }
+            ]
         ]);
 
         const suffix = 'Proto';
@@ -1146,8 +1154,8 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.MAPROUTE), new List(documents), { infoWindowOpen, ...options }, id);
         }
 
-        export function CalendarDocument(options: DocumentOptions={}, documents: Array<Doc>){
-            return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), options)
+        export function CalendarDocument(options: DocumentOptions, documents: Array<Doc>){
+            return InstanceFromProto(Prototypes.get(DocumentType.CALENDAR), new List(documents), {...options})
         }
 
         // shouldn't ever need to create a KVP document-- instead set the LayoutTemplateString to be a KeyValueBox for the DocumentView (see addDocTab in TabDocView)
diff --git a/src/client/util/CalendarManager.scss b/src/client/util/CalendarManager.scss
index 60610f298..114e19a0e 100644
--- a/src/client/util/CalendarManager.scss
+++ b/src/client/util/CalendarManager.scss
@@ -31,19 +31,20 @@
         margin-top: 10px;
         align-self: center;
         width: 60%;
+    }
 
-        .MuiFilledInput-input{
-            padding: 10px;
-        }
+    .description-container{
+        margin-top: 10px;
+        align-self: center;
+        width: 60%;
     }
 
     .date-range-picker-container{
         margin-top: 5px;
-        align-self:center;
-
-        .react-date-range{
-
-        }
+        align-self: center;
+        display: flex;
+        flex-direction: column;
+        gap: 2px;
     }
 
     .create-button-container{
@@ -57,6 +58,5 @@
             border-radius: 5px;
             background-color: #EFF2F7;
         }
-
     }
 }
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 3872294db..d5d4203b1 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -10,16 +10,16 @@ import { MainViewModal } from '../views/MainViewModal';
 import { TextField } from '@mui/material';
 import Select from 'react-select';
 import { SettingsManager } from './SettingsManager';
-import { DocCast, StrCast } from '../../fields/Types';
+import { DateCast, DocCast, StrCast } from '../../fields/Types';
 import { SelectionManager } from './SelectionManager';
 import { DocumentManager } from './DocumentManager';
 import { DocData } from '../../fields/DocSymbols';
 // import { DateRange, Range, RangeKeyDict } from 'react-date-range';
 import { Button } from 'browndash-components';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Provider, useProvider, defaultTheme } from '@adobe/react-spectrum';
-
-import { DateRangePicker } from '@adobe/react-spectrum';
+import { Provider, defaultTheme } from '@adobe/react-spectrum';
+import { DateValue } from '@internationalized/date';
+import { DateRangePicker, SpectrumDateRangePickerProps } from '@adobe/react-spectrum';
 import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
 import { Docs } from '../documents/Documents';
 import { ObservableReactComponent } from '../views/ObservableReactComponent';
@@ -33,7 +33,10 @@ interface CalendarSelectOptions {
     value: string;
 }
 
-const formatDateToString = (date: Date) => {
+const formatCalendarDateToString = (calendarDate: any) => {
+    console.log("Formatting the following date: ", calendarDate);
+    const date = new Date(calendarDate.year, calendarDate.month-1, calendarDate.day)
+    console.log(typeof date);
     const year = date.getFullYear();
     const month = String(date.getMonth() + 1).padStart(2, '0');
     const day = String(date.getDate()).padStart(2, '0');
@@ -121,19 +124,26 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     };
 
     @action
-    handleTextFieldChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+    handleCalendarTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
         this.calendarName = event.target.value;
     };
 
+    @action
+    handleCalendarDescriptionChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+        this.calendarDescription = event.target.value;
+    }
+
     // TODO: Make undoable
     private addToCalendar = () => {
         let docs = SelectionManager.Views.length < 2 ? [this.targetDoc] : SelectionManager.Views.map(docView => docView.Document);
         const targetDoc = this.layoutDocAcls ? docs[0] : docs[0]?.[DocData]; // doc to add to calendar
 
+        console.log(targetDoc);
         if (targetDoc) {
             let calendar: Doc;
             if (this.creationType === 'new-calendar') {
                 if (!this.existingCalendars.find(doc => StrCast(doc.title) === this.calendarName)) {
+                    console.log('creating...')
                     calendar = Docs.Create.CalendarDocument(
                         {
                             title: this.calendarName,
@@ -141,6 +151,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                         },
                         []
                     );
+                    console.log('successful calendar creation')
                 } else {
                     this.errorMessage = 'Calendar with this name already exists';
                     return;
@@ -155,15 +166,20 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                 }
             }
             // Get start and end date strings
-            const startDateStr = formatDateToString(this.selectedDateRange.start);
-            const endDateStr = formatDateToString(this.selectedDateRange.end);
+            const startDateStr = formatCalendarDateToString(this.selectedDateRange.start);
+            const endDateStr = formatCalendarDateToString(this.selectedDateRange.end);
+
+            console.log("start date: ", startDateStr);
+            console.log("end date: ", endDateStr)
 
             const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding
+            console.log("subdoc embedding", subDocEmbedding);
             subDocEmbedding.embedContainer = calendar; // set embed container
             subDocEmbedding.date_range = `${startDateStr}-${endDateStr}`; // set subDoc date range
 
             Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar
 
+            console.log("my calendars: ", Doc.MyCalendars);
             if (this.creationType === 'new-calendar') {
                 Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
             }
@@ -211,6 +227,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
 
     @action
     setSelectedDateRange = (range: any) => {
+        console.log("Range: ", range);
         this.selectedDateRange = range;
     };
 
@@ -220,9 +237,12 @@ export class CalendarManager extends ObservableReactComponent<{}> {
         let startDate: Date | undefined;
         let endDate: Date | undefined;
         try {
-            startDate = this.selectedDateRange[0].startDate;
-            endDate = this.selectedDateRange[0].endDate;
+            startDate = this.selectedDateRange.start;
+            endDate = this.selectedDateRange.end;
+            console.log(startDate);
+            console.log(endDate)
         } catch (e: any) {
+            console.log(e);
             return false; // disabled
         }
         if (!startDate || !endDate) return false; // disabled if any is undefined
@@ -258,8 +278,9 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                     {this.creationType === 'new-calendar' ? (
                         <TextField
                             fullWidth
-                            onChange={this.handleTextFieldChange}
-                            placeholder="Enter calendar name..."
+                            onChange={this.handleCalendarTitleChange}
+                            label='Calendar name'
+                            placeholder='Enter a name...'
                             variant="filled"
                             style={{
                                 backgroundColor: 'white',
@@ -298,14 +319,41 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                             }}></Select>
                     )}
                 </div>
+                <div className='description-container'>
+                    <TextField
+                        fullWidth
+                        multiline
+                        label='Calendar description'
+                        placeholder='Enter a description (optional)...'
+                        onChange={this.handleCalendarDescriptionChange}
+                        variant="filled"
+                        style={{
+                            backgroundColor: 'white',
+                            color: 'black',
+                            borderRadius: '5px',
+                        }}
+                    />
+                </div>
                 <div className="date-range-picker-container">
+                    <div>Select a date range: </div>
                     <Provider theme={defaultTheme}>
-                        <DateRangePicker value={this.selectedDateRange} onChange={v => this.setSelectedDateRange(v)} label="Date range" />
+                        <DateRangePicker 
+                            aria-label='Select a date range'
+                            value={this.selectedDateRange} 
+                            onChange={v => this.setSelectedDateRange(v)}/>
                     </Provider>
                 </div>
-                <div className="create-button-container">
-                    <Button active={this.createButtonActive} onClick={() => {}} text="Add to Calendar" iconPlacement="right" icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
-                </div>
+                {this.createButtonActive && 
+                    <div className='create-button-container'>
+                        <Button 
+                            onClick={() => this.addToCalendar()} 
+                            text="Add to Calendar" 
+                            iconPlacement="right" 
+                            icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
+                    </div>
+                    
+                }
+                
             </div>
         );
     }
@@ -313,4 +361,4 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     render() {
         return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
     }
-}
+}
\ No newline at end of file
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 61a9fa7c2..f7070a862 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1022,4 +1022,4 @@ ScriptingGlobals.add(function IsExploreMode() { return DocumentView.ExploreMode;
 ScriptingGlobals.add(function IsNoviceMode() { return Doc.noviceMode; }, "is Dash in novice mode");
 ScriptingGlobals.add(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; }, "switches between comic and normal document rendering");
 ScriptingGlobals.add(function importDocument() { return CurrentUserUtils.importDocument(); }, "imports files from device directly into the import sidebar");
-ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; });
+ScriptingGlobals.add(function setInkToolDefaults() { Doc.ActiveTool = InkTool.None; });
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
new file mode 100644
index 000000000..99dc09732
--- /dev/null
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+import { CollectionSubView } from "./CollectionSubView";
+import { observer } from 'mobx-react';
+import { makeObservable, observable } from 'mobx';
+import { Doc, DocListCast } from '../../../fields/Doc';
+
+@observer
+export class CollectionCalendarView extends CollectionSubView(){
+
+    constructor(props: any){
+        super(props);
+        makeObservable(this);
+    }
+
+    componentDidMount(): void {
+        
+    }
+
+    componentWillUnmount(): void {
+        
+    }
+
+    @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars?.data);
+
+    render(){
+        return (
+            <div>
+                Hello
+            </div>
+        )
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0673b264b..0237ec95e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -28,6 +28,7 @@ import { CollectionTreeView } from './CollectionTreeView';
 import './CollectionView.scss';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionGridView } from './collectionGrid/CollectionGridView';
+import { CollectionCalendarView} from './CollectionCalendarView';
 import { CollectionLinearView } from './collectionLinear';
 import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
 import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView';
@@ -122,6 +123,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             default:
             case CollectionViewType.Freeform:     return <CollectionFreeFormView    key="collview" {...props} />;
             case CollectionViewType.Schema:       return <CollectionSchemaView      key="collview" {...props} />;
+            case CollectionViewType.Calendar:     return <CollectionCalendarView    key="collview" {...props} />;
             case CollectionViewType.Docking:      return <CollectionDockingView     key="collview" {...props} />;
             case CollectionViewType.Tree:         return <CollectionTreeView        key="collview" {...props} />;
             case CollectionViewType.Multicolumn:  return <CollectionMulticolumnView key="collview" {...props} />;
@@ -146,6 +148,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
                 { description: 'Schema',      event: () => func(CollectionViewType.Schema), icon: 'th-list' },
                 { description: 'Tree',        event: () => func(CollectionViewType.Tree), icon: 'tree' },
                 { description: 'Stacking',    event: () => (func(CollectionViewType.Stacking)._layout_autoHeight = true), icon: 'ellipsis-v' },
+                { description: 'Calendar',    event: () => func(CollectionViewType.Calendar), icon: 'columns'},
                 { description: 'Notetaking',  event: () => (func(CollectionViewType.NoteTaking)._layout_autoHeight = true), icon: 'ellipsis-v' },
                 { description: 'Multicolumn', event: () => func(CollectionViewType.Multicolumn), icon: 'columns' },
                 { description: 'Multirow',    event: () => func(CollectionViewType.Multirow), icon: 'columns' },
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e161b4c4c..5b2bf4774 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -14,6 +14,7 @@ import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { CollectionView } from '../collections/CollectionView';
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
 import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
+import { CollectionCalendarView } from '../collections/CollectionCalendarView';
 import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox';
 import { PresElementBox } from '../nodes/trails/PresElementBox';
 import { SearchBox } from '../search/SearchBox';
@@ -243,6 +244,7 @@ export class DocumentContentsView extends ObservableReactComponent<
                     CollectionFreeFormView,
                     CollectionDockingView,
                     CollectionSchemaView,
+                    CollectionCalendarView,
                     CollectionView,
                     WebBox,
                     KeyValueBox,
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index b627ba459..44afb8e7b 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -23,9 +23,7 @@ import { FieldView, FieldViewProps } from '../FieldView';
 import { FormattedTextBox } from '../formattedText/FormattedTextBox';
 import { PinProps, PresBox } from '../trails';
 import { MapAnchorMenu } from './MapAnchorMenu';
-
 import { ControlPosition, Layer, MapProvider, MapRef, Map as MapboxMap, Marker, MarkerProps, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl';
-import MapboxGeocoder, { GeocoderOptions } from '@mapbox/mapbox-gl-geocoder!';
 import './MapBox.scss';
 // import { GeocoderControl } from './GeocoderControl';
 import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
@@ -33,7 +31,7 @@ import { Checkbox, FormControlLabel, TextField } from '@mui/material';
 import * as turf from '@turf/turf';
 import * as d3 from 'd3';
 import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson';
-import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl!';
+import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from '!mapbox-gl';
 import { CirclePicker, ColorResult } from 'react-color';
 import { MarkerEvent } from 'react-map-gl/dist/esm/types';
 import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons';
@@ -68,13 +66,13 @@ type PopupInfo = {
     description: string;
 };
 
-export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
-    mapboxAccessToken: string;
-    marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
-    position: ControlPosition;
+// export type GeocoderControlProps = Omit<GeocoderOptions, 'accessToken' | 'mapboxgl' | 'marker'> & {
+//     mapboxAccessToken: string;
+//     marker?: Omit<MarkerProps, 'longitude' | 'latitude'>;
+//     position: ControlPosition;
 
-    onResult: (...args: any[]) => void;
-};
+//     onResult: (...args: any[]) => void;
+// };
 
 type MapMarker = {
     longitude: number;
@@ -1866,4 +1864,4 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                         <div style={{ width: 30, height: 30 }} ref={this._dragRef} onPointerDown={this.dragToggle}>
                             <Button tooltip="drag to place a pushpin" icon={<FontAwesomeIcon size={'lg'} icon={'bullseye'} />} />
                         </div> */
-}
+}
\ No newline at end of file
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
new file mode 100644
index 000000000..0aa3b4ccc
--- /dev/null
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -0,0 +1,26 @@
+import * as React from 'react';
+import { observer } from "mobx-react";
+import { Doc } from "../../../../fields/Doc";
+import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps, ViewBoxBaseComponent } from '../../DocComponent';
+import { FieldView, FieldViewProps } from '../FieldView';
+import { StrCast } from '../../../../fields/Types';
+import { makeObservable } from 'mobx';
+
+@observer
+export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
+    public static LayoutString(fieldKey: string = 'calendar') {
+        return FieldView.LayoutString(CalendarBox, fieldKey);
+    }
+
+    constructor(props: any){
+        super(props);
+        makeObservable(this);
+    }
+
+    render(){
+        return (
+            <div></div>  
+        );
+        
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 6e78d5d0bf88d25db48a82e498fe0193dc9baedf Mon Sep 17 00:00:00 2001
From: zaultavangar <zaul_tavangar@brown.edu>
Date: Sun, 17 Dec 2023 20:13:21 -0500
Subject: developing CalendarBox and CollectionCalendarView

---
 package-lock.json                                  |  39 ++++++++
 package.json                                       |   3 +
 src/Utils.ts                                       |  21 ++++
 src/client/util/CalendarManager.tsx                |   3 +-
 .../views/collections/CollectionCalendarView.tsx   | 103 ++++++++++++++++++-
 src/client/views/nodes/calendarBox/CalendarBox.tsx | 110 ++++++++++++++++++++-
 6 files changed, 273 insertions(+), 6 deletions(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/package-lock.json b/package-lock.json
index 2d2740381..ed66d83a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,9 @@
                 "@fortawesome/free-regular-svg-icons": "^6.5.1",
                 "@fortawesome/free-solid-svg-icons": "^6.5.1",
                 "@fortawesome/react-fontawesome": "^0.2.0",
+                "@fullcalendar/core": "^6.1.10",
+                "@fullcalendar/daygrid": "^6.1.10",
+                "@fullcalendar/multimonth": "^6.1.10",
                 "@internationalized/date": "^3.5.0",
                 "@mapbox/mapbox-gl-geocoder": "^5.0.2",
                 "@mui/icons-material": "^5.14.19",
@@ -2653,6 +2656,33 @@
                 "react": ">=16.3"
             }
         },
+        "node_modules/@fullcalendar/core": {
+            "version": "6.1.10",
+            "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.10.tgz",
+            "integrity": "sha512-oTXGJSAGpCf1oY+CKp5qYjMHkJCPBkJ3SHitl63n8Q6xKeiwQ4EF6Au451euUovREwJpLmD1AyZrCnWmtB9AVg==",
+            "dependencies": {
+                "preact": "~10.12.1"
+            }
+        },
+        "node_modules/@fullcalendar/daygrid": {
+            "version": "6.1.10",
+            "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.10.tgz",
+            "integrity": "sha512-Z4GRm1IyHKgxXFTWGcEI0nTsvYOIkpE0aMt3/o3ER2SZkF+hfwcDFhtj0c9+WhMjXFIWYeoTnA9rUOY7Zl/nxA==",
+            "peerDependencies": {
+                "@fullcalendar/core": "~6.1.10"
+            }
+        },
+        "node_modules/@fullcalendar/multimonth": {
+            "version": "6.1.10",
+            "resolved": "https://registry.npmjs.org/@fullcalendar/multimonth/-/multimonth-6.1.10.tgz",
+            "integrity": "sha512-mLGEgD+sv8rNfKphyOCWRQapX7/nAvHgQmDTjuy4STlhHsddCYVmFlsSgF373ph1tXh41wAJUVdNO/pDmCvUfA==",
+            "dependencies": {
+                "@fullcalendar/daygrid": "~6.1.10"
+            },
+            "peerDependencies": {
+                "@fullcalendar/core": "~6.1.10"
+            }
+        },
         "node_modules/@googlemaps/js-api-loader": {
             "version": "1.16.2",
             "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
@@ -29048,6 +29078,15 @@
             "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.0.0.tgz",
             "integrity": "sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw=="
         },
+        "node_modules/preact": {
+            "version": "10.12.1",
+            "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz",
+            "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==",
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/preact"
+            }
+        },
         "node_modules/prelude-ls": {
             "version": "1.2.1",
             "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
diff --git a/package.json b/package.json
index 098e30ffb..6f0911a2d 100644
--- a/package.json
+++ b/package.json
@@ -106,6 +106,9 @@
         "@fortawesome/free-regular-svg-icons": "^6.5.1",
         "@fortawesome/free-solid-svg-icons": "^6.5.1",
         "@fortawesome/react-fontawesome": "^0.2.0",
+        "@fullcalendar/core": "^6.1.10",
+        "@fullcalendar/daygrid": "^6.1.10",
+        "@fullcalendar/multimonth": "^6.1.10",
         "@internationalized/date": "^3.5.0",
         "@mapbox/mapbox-gl-geocoder": "^5.0.2",
         "@mui/icons-material": "^5.14.19",
diff --git a/src/Utils.ts b/src/Utils.ts
index 5f9475f23..a060e4a2c 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -895,3 +895,24 @@ export function setupMoveUpEvents(
     document.addEventListener('pointerup', _upEvent, true);
     document.addEventListener('click', _clickEvent, true);
 }
+
+export function dateRangeStrToDates (dateStr: string) {
+    // dateStr in yyyy-mm-dd format
+    const dateRangeParts = dateStr.split("|"); // splits into from and to date
+    const fromParts = dateRangeParts[0].split("-");
+    const toParts = dateRangeParts[1].split("-");
+
+    const fromYear = parseInt(fromParts[0]);
+    const fromMonth = parseInt(fromParts[1])-1;
+    const fromDay = parseInt(fromParts[2]);
+
+    const toYear = parseInt(toParts[0]);
+    const toMonth = parseInt(toParts[1])-1;
+    const toDay = parseInt(toParts[2]);
+
+
+    return [
+        new Date(fromYear, fromMonth, fromDay),
+        new Date(toYear, toMonth, toDay)
+    ];
+}
\ No newline at end of file
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index d5d4203b1..c3e54ebd3 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -125,6 +125,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
 
     @action
     handleCalendarTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
+        console.log("Existing calendars: ", this.existingCalendars);
         this.calendarName = event.target.value;
     };
 
@@ -175,7 +176,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
             const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding
             console.log("subdoc embedding", subDocEmbedding);
             subDocEmbedding.embedContainer = calendar; // set embed container
-            subDocEmbedding.date_range = `${startDateStr}-${endDateStr}`; // set subDoc date range
+            subDocEmbedding.date_range = `${startDateStr}|${endDateStr}`; // set subDoc date range
 
             Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar
 
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index 99dc09732..f94d05c61 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -1,8 +1,18 @@
 import * as React from 'react';
 import { CollectionSubView } from "./CollectionSubView";
 import { observer } from 'mobx-react';
-import { makeObservable, observable } from 'mobx';
-import { Doc, DocListCast } from '../../../fields/Doc';
+import { computed, makeObservable, observable } from 'mobx';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { CollectionStackingView } from './CollectionStackingView';
+import { CollectionViewType } from '../../documents/DocumentTypes';
+import { dateRangeStrToDates, emptyFunction, returnAll, returnEmptyDoclist, returnNone, returnOne, returnTrue } from '../../../Utils';
+import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
+import { TbRuler } from 'react-icons/tb';
+import { Transform } from '../../util/Transform';
+import { DocData } from '../../../fields/DocSymbols';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { StyleProp } from '../StyleProvider';
+import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
 
 @observer
 export class CollectionCalendarView extends CollectionSubView(){
@@ -20,13 +30,98 @@ export class CollectionCalendarView extends CollectionSubView(){
         
     }
 
-    @observable private existingCalendars: Doc[] = DocListCast(Doc.MyCalendars?.data);
+    @computed get allCalendars(){
+        return this.childDocs; // returns a list of docs (i.e. calendars)
+    }
+
+    removeCalendar = () => {
+
+    }
+
+    addCalendar = (doc: Doc | Doc[], annotationKey?: string | undefined): boolean => {
+        // bring up calendar modal with option to create a calendar 
+        return true;
+    }
+
+    _stackRef = React.createRef<CollectionStackingView>();
+
+    panelHeight = () => {
+        return 0; // a standard height for all calendars; TODO: change
+    }
+
+    panelWidth = () => {
+        return 0; //a standard width for all calendars; TODO: change
+    }
+
+    // most recent calendar should come first
+    sortByMostRecentDate = (calendarA: Doc, calendarB: Doc) => {
+        const aDateRangeStr = StrCast(calendarA.date_range);
+        const bDateRangeStr = StrCast(calendarB.date_range);
+
+        const [aFromDate, aToDate] = dateRangeStrToDates(aDateRangeStr);
+        const [bFromDate, bToDate] = dateRangeStrToDates(bDateRangeStr);
+        
+        if (aFromDate > bFromDate) { 
+            return -1; // a comes first
+        } else if (aFromDate < bFromDate) {
+            return 1; // b comes first
+        } else { // start dates are the same
+            if (aToDate > bToDate) {
+                return -1; // a comes first
+            } else if (aToDate < bToDate) {
+                return 1; // b comes first
+            } else {
+                return 0; // same start and end dates
+            }
+        }
+
+
+    }
+
+    
+
+    screenToLocalTransform = () =>
+        this._props
+            .ScreenToLocalTransform()
+            .translate(Doc.NativeWidth(this._props.Document), 0)
+            .scale(this._props.NativeDimScaling?.() || 1);
+
+    get calendarsKey() {
+        return this._props.fieldKey + '_calendars';
+    }
 
     render(){
         return (
             <div>
-                Hello
+                 <CollectionStackingView
+                        {...this._props}
+                        setContentView={emptyFunction}
+                        // NativeWidth={}
+                        // NativeHeight={returnZero}
+                        ref={this._stackRef}
+                        PanelHeight={this.panelHeight}
+                        PanelWidth={this.panelWidth}
+                        // childFilters={this.childFilters} DO I NEED THIS?
+                        sortFunc={this.sortByMostRecentDate}
+                        setHeight={this.setHeightCallback}
+                        isAnnotationOverlay={false}
+                        // select={emptyFunction} What does this mean?
+                        NativeDimScaling={returnOne}
+                        isAnyChildContentActive={returnTrue} // ??
+                        // childDocumentsActive={}
+                        // whenChildContentsActiveChanged={}
+                        childHideDecorationTitle={false}
+                        removeDocument={this.removeDocument} // will calendar automatically be removed from myCalendars
+                        moveDocument={this.moveDocument}
+                        addDocument={this.addCalendar}
+                        ScreenToLocalTransform={this.screenToLocalTransform}
+                        renderDepth={this._props.renderDepth + 1}
+                        type_collection={CollectionViewType.Stacking}
+                        fieldKey={this.calendarsKey}
+                        pointerEvents={returnAll}
+                    />
             </div>
+
         )
     }
 }
\ No newline at end of file
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 0aa3b4ccc..989feb774 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -5,6 +5,13 @@ import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps, ViewBoxBaseCompon
 import { FieldView, FieldViewProps } from '../FieldView';
 import { StrCast } from '../../../../fields/Types';
 import { makeObservable } from 'mobx';
+import { dateRangeStrToDates } from '../../../../Utils';
+import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core'
+import dayGridPlugin from '@fullcalendar/daygrid'
+import multiMonthPlugin from '@fullcalendar/multimonth'
+import { faListNumeric } from '@fortawesome/free-solid-svg-icons';
+
+type CalendarView = 'month' | 'multi-month' | 'week';
 
 @observer
 export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
@@ -12,6 +19,103 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
         return FieldView.LayoutString(CalendarBox, fieldKey);
     }
 
+    componentDidMount(): void {
+        
+    }
+
+    componentWillUnmount(): void {
+        
+    }
+
+    _calendarRef = React.createRef<HTMLElement>()
+
+    get dateRangeStr (){
+        return StrCast(this.Document.date_range);
+    }
+
+    // Choose a calendar view based on the date range 
+    get calendarViewType (): CalendarView {
+        const [fromDate, toDate] = dateRangeStrToDates(this.dateRangeStr);
+
+        if (fromDate.getFullYear() !== toDate.getFullYear() || fromDate.getMonth() !== toDate.getMonth()) return 'multi-month';
+
+        if (Math.abs(fromDate.getDay() - toDate.getDay()) > 7) return 'month';
+        return 'week';
+    }
+
+    get calendarStartDate () {
+        return this.dateRangeStr.split("|")[0];
+    }
+
+    get calendarToDate () {
+        return this.dateRangeStr.split("|")[1];
+    }
+
+    get childDocs (): Doc[] {
+        return this.childDocs; // get all sub docs for a calendar
+    }
+
+    docBackgroundColor (type: string): string {
+        // TODO: Return a different color based on the event type
+        return 'blue';
+    }
+
+    get calendarEvents (): EventSourceInput | undefined {
+        if (this.childDocs.length === 0) return undefined;
+        return this.childDocs.map((doc, idx) => {
+            const docTitle = StrCast(doc.title);
+            const docDateRange = StrCast(doc.date_range);
+            const [startDate, endDate] = dateRangeStrToDates(docDateRange);
+            const docType = doc.type;
+            const docDescription = doc.description ? StrCast(doc.description): "";
+
+            return {
+                title: docTitle,
+                start: startDate,
+                end: endDate,
+                allDay: false,
+                classNames:[StrCast(docType)], // will determine the style 
+                editable: false, // subject to change in the future
+                backgroundColor: this.docBackgroundColor(StrCast(doc.type)),
+                color: 'white',
+                extendedProps: {
+                    description: docDescription
+                },
+                
+            }
+
+        })
+    }
+
+    handleEventClick = (arg: EventClickArg) => {
+        // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc.
+    }
+
+    calendarEl: HTMLElement = document.getElementById('calendar-box-v1')!;
+
+    // https://fullcalendar.io
+    get calendar() {
+        return new Calendar(this.calendarEl, 
+            {
+                plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin],
+                headerToolbar: {
+                    left: 'prev,next today',
+                    center: 'title',
+                    right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
+                },
+                initialDate: this.calendarStartDate,
+                navLinks: true,
+                editable: false,
+                displayEventTime: false,
+                displayEventEnd: false,
+                events: this.calendarEvents,
+                eventClick: this.handleEventClick
+            }
+        )
+        
+    }
+
+
     constructor(props: any){
         super(props);
         makeObservable(this);
@@ -19,7 +123,11 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
 
     render(){
         return (
-            <div></div>  
+            <div className='calendar-box-conatiner'>
+                <div id='calendar-box-v1'>
+
+                </div>
+            </div>  
         );
         
     }
-- 
cgit v1.2.3-70-g09d2


From 63c5625b34d42f33270067c27047d597fd9b46ce Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 17 Dec 2023 21:47:22 -0500
Subject: tweaked some things with CalendarView

---
 src/client/util/CalendarManager.tsx                |  63 ++++++-------
 .../views/collections/CollectionCalendarView.tsx   | 101 +++++++++------------
 src/client/views/collections/CollectionSubView.tsx |   2 +-
 3 files changed, 73 insertions(+), 93 deletions(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index c3e54ebd3..6ef2d3429 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -34,8 +34,8 @@ interface CalendarSelectOptions {
 }
 
 const formatCalendarDateToString = (calendarDate: any) => {
-    console.log("Formatting the following date: ", calendarDate);
-    const date = new Date(calendarDate.year, calendarDate.month-1, calendarDate.day)
+    console.log('Formatting the following date: ', calendarDate);
+    const date = new Date(calendarDate.year, calendarDate.month - 1, calendarDate.day);
     console.log(typeof date);
     const year = date.getFullYear();
     const month = String(date.getMonth() + 1).padStart(2, '0');
@@ -118,21 +118,23 @@ export class CalendarManager extends ObservableReactComponent<{}> {
 
     @action
     handleSelectChange = (option: any) => {
-        let selectOpt = option as CalendarSelectOptions;
-        this.selectedExistingCalendarOption = selectOpt;
-        this.calendarName = selectOpt.value; // or label
+        if (option) {
+            let selectOpt = option as CalendarSelectOptions;
+            this.selectedExistingCalendarOption = selectOpt;
+            this.calendarName = selectOpt.value; // or label
+        }
     };
 
     @action
     handleCalendarTitleChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
-        console.log("Existing calendars: ", this.existingCalendars);
+        console.log('Existing calendars: ', this.existingCalendars);
         this.calendarName = event.target.value;
     };
 
     @action
     handleCalendarDescriptionChange = (event: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
         this.calendarDescription = event.target.value;
-    }
+    };
 
     // TODO: Make undoable
     private addToCalendar = () => {
@@ -144,7 +146,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
             let calendar: Doc;
             if (this.creationType === 'new-calendar') {
                 if (!this.existingCalendars.find(doc => StrCast(doc.title) === this.calendarName)) {
-                    console.log('creating...')
+                    console.log('creating...');
                     calendar = Docs.Create.CalendarDocument(
                         {
                             title: this.calendarName,
@@ -152,7 +154,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                         },
                         []
                     );
-                    console.log('successful calendar creation')
+                    console.log('successful calendar creation');
                 } else {
                     this.errorMessage = 'Calendar with this name already exists';
                     return;
@@ -170,17 +172,17 @@ export class CalendarManager extends ObservableReactComponent<{}> {
             const startDateStr = formatCalendarDateToString(this.selectedDateRange.start);
             const endDateStr = formatCalendarDateToString(this.selectedDateRange.end);
 
-            console.log("start date: ", startDateStr);
-            console.log("end date: ", endDateStr)
+            console.log('start date: ', startDateStr);
+            console.log('end date: ', endDateStr);
 
             const subDocEmbedding = Doc.MakeEmbedding(targetDoc); // embedding
-            console.log("subdoc embedding", subDocEmbedding);
+            console.log('subdoc embedding', subDocEmbedding);
             subDocEmbedding.embedContainer = calendar; // set embed container
             subDocEmbedding.date_range = `${startDateStr}|${endDateStr}`; // set subDoc date range
 
             Doc.AddDocToList(calendar, 'data', subDocEmbedding); // add embedded subDoc to calendar
 
-            console.log("my calendars: ", Doc.MyCalendars);
+            console.log('my calendars: ', Doc.MyCalendars);
             if (this.creationType === 'new-calendar') {
                 Doc.AddDocToList(Doc.MyCalendars, 'data', calendar); // add to new calendar to dashboard calendars
             }
@@ -228,7 +230,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
 
     @action
     setSelectedDateRange = (range: any) => {
-        console.log("Range: ", range);
+        console.log('Range: ', range);
         this.selectedDateRange = range;
     };
 
@@ -241,7 +243,7 @@ export class CalendarManager extends ObservableReactComponent<{}> {
             startDate = this.selectedDateRange.start;
             endDate = this.selectedDateRange.end;
             console.log(startDate);
-            console.log(endDate)
+            console.log(endDate);
         } catch (e: any) {
             console.log(e);
             return false; // disabled
@@ -280,8 +282,8 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                         <TextField
                             fullWidth
                             onChange={this.handleCalendarTitleChange}
-                            label='Calendar name'
-                            placeholder='Enter a name...'
+                            label="Calendar name"
+                            placeholder="Enter a name..."
                             variant="filled"
                             style={{
                                 backgroundColor: 'white',
@@ -320,12 +322,12 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                             }}></Select>
                     )}
                 </div>
-                <div className='description-container'>
+                <div className="description-container">
                     <TextField
                         fullWidth
                         multiline
-                        label='Calendar description'
-                        placeholder='Enter a description (optional)...'
+                        label="Calendar description"
+                        placeholder="Enter a description (optional)..."
                         onChange={this.handleCalendarDescriptionChange}
                         variant="filled"
                         style={{
@@ -338,23 +340,14 @@ export class CalendarManager extends ObservableReactComponent<{}> {
                 <div className="date-range-picker-container">
                     <div>Select a date range: </div>
                     <Provider theme={defaultTheme}>
-                        <DateRangePicker 
-                            aria-label='Select a date range'
-                            value={this.selectedDateRange} 
-                            onChange={v => this.setSelectedDateRange(v)}/>
+                        <DateRangePicker aria-label="Select a date range" value={this.selectedDateRange} onChange={v => this.setSelectedDateRange(v)} />
                     </Provider>
                 </div>
-                {this.createButtonActive && 
-                    <div className='create-button-container'>
-                        <Button 
-                            onClick={() => this.addToCalendar()} 
-                            text="Add to Calendar" 
-                            iconPlacement="right" 
-                            icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
+                {this.createButtonActive && (
+                    <div className="create-button-container">
+                        <Button onClick={() => this.addToCalendar()} text="Add to Calendar" iconPlacement="right" icon={<FontAwesomeIcon icon={faPlus as IconLookup} />} />
                     </div>
-                    
-                }
-                
+                )}
             </div>
         );
     }
@@ -362,4 +355,4 @@ export class CalendarManager extends ObservableReactComponent<{}> {
     render() {
         return <MainViewModal contents={this.calendarInterface} isDisplayed={this.isOpen} interactive={true} dialogueBoxDisplayedOpacity={this.dialogueBoxOpacity} overlayDisplayedOpacity={this.overlayOpacity} closeOnExternalClick={this.close} />;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index f28154486..ad880b815 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -1,5 +1,5 @@
 import * as React from 'react';
-import { CollectionSubView } from "./CollectionSubView";
+import { CollectionSubView } from './CollectionSubView';
 import { observer } from 'mobx-react';
 import { computed, makeObservable, observable } from 'mobx';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
@@ -15,43 +15,36 @@ import { StyleProp } from '../StyleProvider';
 import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
 
 @observer
-export class CollectionCalendarView extends CollectionSubView(){
-
-    constructor(props: any){
+export class CollectionCalendarView extends CollectionSubView() {
+    constructor(props: any) {
         super(props);
         makeObservable(this);
     }
 
-    componentDidMount(): void {
-        
-    }
+    componentDidMount(): void {}
 
-    componentWillUnmount(): void {
-        
-    }
+    componentWillUnmount(): void {}
 
-    @computed get allCalendars(){
+    @computed get allCalendars() {
         return this.childDocs; // returns a list of docs (i.e. calendars)
     }
 
-    removeCalendar = () => {
-
-    }
+    removeCalendar = () => {};
 
     addCalendar = (doc: Doc | Doc[], annotationKey?: string | undefined): boolean => {
-        // bring up calendar modal with option to create a calendar 
+        // bring up calendar modal with option to create a calendar
         return true;
-    }
+    };
 
     _stackRef = React.createRef<CollectionStackingView>();
 
     panelHeight = () => {
         return 0; // TODO: change
-    }
+    };
 
     panelWidth = () => {
         return 0; // TODO: change
-    }
+    };
 
     // most recent calendar should come first
     sortByMostRecentDate = (calendarA: Doc, calendarB: Doc) => {
@@ -60,12 +53,13 @@ export class CollectionCalendarView extends CollectionSubView(){
 
         const [aFromDate, aToDate] = dateRangeStrToDates(aDateRangeStr);
         const [bFromDate, bToDate] = dateRangeStrToDates(bDateRangeStr);
-        
-        if (aFromDate > bFromDate) { 
+
+        if (aFromDate > bFromDate) {
             return -1; // a comes first
         } else if (aFromDate < bFromDate) {
             return 1; // b comes first
-        } else { // start dates are the same
+        } else {
+            // start dates are the same
             if (aToDate > bToDate) {
                 return -1; // a comes first
             } else if (aToDate < bToDate) {
@@ -74,11 +68,7 @@ export class CollectionCalendarView extends CollectionSubView(){
                 return 0; // same start and end dates
             }
         }
-
-
-    }
-
-    
+    };
 
     screenToLocalTransform = () =>
         this._props
@@ -90,38 +80,35 @@ export class CollectionCalendarView extends CollectionSubView(){
         return this._props.fieldKey + '_calendars';
     }
 
-    render(){
+    render() {
         return (
             <div>
-                 <CollectionStackingView
-                        {...this._props}
-                        setContentView={emptyFunction}
-                        NativeWidth={}
-                        NativeHeight={}
-                        ref={this._stackRef}
-                        PanelHeight={this.panelHeight}
-                        PanelWidth={this.panelWidth}
-                        // childFilters={this.childFilters} DO I NEED THIS?
-                        sortFunc={this.sortByMostRecentDate}
-                        setHeight={this.setHeightCallback}
-                        isAnnotationOverlay={false}
-                        // select={emptyFunction} What does this mean?
-                        NativeDimScaling={returnOne}
-                        isAnyChildContentActive={returnTrue} // ??
-                        // childDocumentsActive={}
-                        // whenChildContentsActiveChanged={}
-                        childHideDecorationTitle={false}
-                        removeDocument={this.removeDocument} // will calendar automatically be removed from myCalendars
-                        moveDocument={this.moveDocument}
-                        addDocument={this.addCalendar}
-                        ScreenToLocalTransform={this.screenToLocalTransform}
-                        renderDepth={this._props.renderDepth + 1}
-                        type_collection={CollectionViewType.Stacking}
-                        fieldKey={this.calendarsKey}
-                        pointerEvents={returnAll}
-                    />
+                <CollectionStackingView
+                    {...this._props}
+                    setContentView={emptyFunction}
+                    ref={this._stackRef}
+                    PanelHeight={this.panelHeight}
+                    PanelWidth={this.panelWidth}
+                    // childFilters={this.childFilters} DO I NEED THIS?
+                    sortFunc={this.sortByMostRecentDate}
+                    setHeight={undefined}
+                    isAnnotationOverlay={false}
+                    // select={emptyFunction} What does this mean?
+                    NativeDimScaling={returnOne}
+                    isAnyChildContentActive={returnTrue} // ??
+                    // childDocumentsActive={}
+                    // whenChildContentsActiveChanged={}
+                    childHideDecorationTitle={false}
+                    removeDocument={this.removeDocument} // will calendar automatically be removed from myCalendars
+                    moveDocument={this.moveDocument}
+                    addDocument={this.addCalendar}
+                    ScreenToLocalTransform={this.screenToLocalTransform}
+                    renderDepth={this._props.renderDepth + 1}
+                    type_collection={CollectionViewType.Stacking}
+                    fieldKey={this.calendarsKey}
+                    pointerEvents={returnAll}
+                />
             </div>
-
-        )
+        );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 0131af6f2..b56973dc6 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -212,7 +212,7 @@ export function CollectionSubView<X>(moreProps?: X) {
 
         addDocument = (doc: Doc | Doc[], annotationKey?: string) => this._props.addDocument?.(doc, annotationKey) || false;
         removeDocument = (doc: Doc | Doc[], annotationKey?: string) => this._props.removeDocument?.(doc, annotationKey) || false;
-        moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string) => this._props.moveDocument?.(doc, targetCollection, addDocument);
+        moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string) => this._props.moveDocument?.(doc, targetCollection, addDocument) || false;
 
         protected onInternalDrop(e: Event, de: DragManager.DropEvent): boolean {
             const docDragData = de.complete.docDragData;
-- 
cgit v1.2.3-70-g09d2


From 9b9f54a43793ca6ffb26c56f962d11ba8325abd2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 29 Dec 2023 17:01:40 -0500
Subject: cleaned up imports, mobx observable initialization and some compile
 errors.

---
 src/Utils.ts                                       |  27 ++---
 src/client/util/CalendarManager.tsx                |  34 +++---
 src/client/util/CaptureManager.tsx                 |   2 +-
 src/client/util/CurrentUserUtils.ts                |  14 +--
 src/client/util/GroupManager.tsx                   |   2 +-
 src/client/util/HypothesisUtils.ts                 |  13 ++-
 src/client/views/DocumentButtonBar.tsx             |   5 -
 src/client/views/DocumentDecorations.tsx           |  11 +-
 src/client/views/FilterPanel.tsx                   |  11 +-
 src/client/views/GestureOverlay.tsx                |  25 +++--
 src/client/views/InkTranscription.tsx              |   8 +-
 src/client/views/InkingStroke.tsx                  |  76 +++++---------
 src/client/views/MainView.tsx                      |   2 +-
 src/client/views/MetadataEntryMenu.tsx             |  12 +--
 src/client/views/PreviewCursor.tsx                 |   2 +-
 src/client/views/PropertiesButtons.tsx             |  17 +--
 .../views/PropertiesDocBacklinksSelector.tsx       |   4 +-
 src/client/views/PropertiesSection.tsx             |   6 +-
 src/client/views/TemplateMenu.tsx                  |   2 +-
 src/client/views/UndoStack.tsx                     |  22 ++--
 src/client/views/animationtimeline/Region.tsx      |   2 +-
 src/client/views/animationtimeline/Timeline.tsx    |   4 +-
 .../views/animationtimeline/TimelineOverview.tsx   |   2 +-
 src/client/views/animationtimeline/Track.tsx       |   8 +-
 .../views/collections/CollectionCalendarView.tsx   |  19 ++--
 .../views/collections/CollectionDockingView.tsx    |   4 +-
 src/client/views/collections/CollectionMenu.tsx    |   3 -
 .../CollectionNoteTakingViewDivider.tsx            |   2 +-
 .../views/collections/CollectionPileView.tsx       |   2 +-
 .../collections/CollectionStackedTimeline.tsx      |   4 +-
 .../CollectionStackingViewFieldColumn.tsx          |   2 +-
 src/client/views/collections/CollectionSubView.tsx |   8 +-
 .../views/collections/CollectionTimeView.tsx       |  14 +--
 src/client/views/collections/CollectionView.tsx    |   2 +-
 src/client/views/collections/KeyRestrictionRow.tsx |  37 +++----
 src/client/views/collections/TreeView.tsx          |   2 +-
 .../CollectionFreeFormBackgroundGrid.tsx           |   2 +-
 .../CollectionFreeFormInfoState.tsx                |   2 +-
 .../CollectionFreeFormInfoUI.tsx                   |   8 +-
 .../CollectionFreeFormLinksView.tsx                |   4 +-
 .../CollectionFreeFormPannableContents.tsx         |   5 +-
 .../CollectionFreeFormRemoteCursors.tsx            |   4 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   2 +-
 .../collections/collectionFreeForm/MarqueeView.tsx |   5 +-
 .../collectionGrid/CollectionGridView.tsx          |   4 +-
 .../views/collections/collectionGrid/Grid.tsx      |   2 +-
 .../CollectionMulticolumnView.tsx                  |   4 +-
 .../CollectionMultirowView.tsx                     |   3 +-
 .../collectionMulticolumn/MulticolumnResizer.tsx   |   8 +-
 .../MulticolumnWidthLabel.tsx                      |  27 +++--
 .../collectionMulticolumn/MultirowHeightLabel.tsx  |  22 ++--
 .../collectionMulticolumn/MultirowResizer.tsx      |   6 +-
 .../collectionSchema/SchemaColumnHeader.tsx        |   4 +-
 src/client/views/linking/LinkMenuItem.tsx          |   6 +-
 src/client/views/linking/LinkPopup.tsx             |   8 +-
 .../views/linking/LinkRelationshipSearch.tsx       |   2 +-
 .../views/newlightbox/ButtonMenu/ButtonMenu.tsx    |   4 +-
 src/client/views/newlightbox/NewLightboxView.tsx   |  26 ++---
 src/client/views/nodes/DataVizBox/DataVizBox.tsx   |   4 +-
 .../views/nodes/DataVizBox/SchemaCSVPopUp.tsx      |  30 +++---
 .../nodes/DataVizBox/components/Histogram.tsx      |   6 +-
 .../nodes/DataVizBox/components/LineChart.tsx      |  28 ++---
 .../views/nodes/DataVizBox/components/PieChart.tsx |   6 +-
 .../views/nodes/DataVizBox/components/TableBox.tsx |  12 +--
 src/client/views/nodes/DocumentContentsView.tsx    |   6 +-
 src/client/views/nodes/DocumentView.tsx            |   7 +-
 src/client/views/nodes/FaceRectangle.tsx           |   4 +-
 src/client/views/nodes/FaceRectangles.tsx          |   4 +-
 src/client/views/nodes/FieldView.tsx               |   2 +-
 src/client/views/nodes/KeyValuePair.tsx            |   6 +-
 src/client/views/nodes/LinkDescriptionPopup.tsx    |   2 +-
 src/client/views/nodes/LinkDocPreview.tsx          |   8 +-
 src/client/views/nodes/LoadingBox.tsx              |   2 +-
 src/client/views/nodes/MapBox/AnimationUtility.ts  |  13 +--
 .../views/nodes/MapBox/DirectionsAnchorMenu.tsx    |  14 +--
 src/client/views/nodes/MapBox/MapAnchorMenu.tsx    | 106 +++++++------------
 src/client/views/nodes/MapBox/MapBox.tsx           |  60 +++++------
 src/client/views/nodes/MapBox/MapBox2.tsx          |   2 +-
 .../views/nodes/MapboxMapBox/MapboxContainer.tsx   |  20 ++--
 src/client/views/nodes/PDFBox.tsx                  |   2 +-
 .../nodes/PhysicsBox/PhysicsSimulationBox.tsx      |   4 +-
 .../nodes/PhysicsBox/PhysicsSimulationWeight.tsx   |   2 +-
 src/client/views/nodes/RadialMenu.tsx              |   2 +-
 src/client/views/nodes/RadialMenuItem.tsx          |   2 +-
 .../views/nodes/RecordingBox/RecordingBox.tsx      |   4 +-
 src/client/views/nodes/ScreenshotBox.tsx           |   2 +-
 src/client/views/nodes/ScriptingBox.tsx            |   8 +-
 src/client/views/nodes/TaskCompletedBox.tsx        |   8 +-
 src/client/views/nodes/VideoBox.tsx                |   6 +-
 src/client/views/nodes/audio/AudioWaveform.tsx     |   2 +-
 src/client/views/nodes/calendarBox/CalendarBox.tsx | 114 +++++++++------------
 .../views/nodes/formattedText/DashDocView.tsx      |   6 +-
 .../views/nodes/formattedText/EquationView.tsx     |   7 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   4 +-
 .../views/nodes/formattedText/RichTextMenu.tsx     |   2 +-
 .../views/nodes/importBox/ImportElementBox.tsx     |   8 +-
 src/client/views/nodes/trails/PresBox.tsx          |   6 +-
 src/client/views/pdf/Annotation.tsx                |   5 +-
 src/client/views/pdf/GPTPopup/GPTPopup.tsx         |  16 +--
 src/client/views/pdf/PDFViewer.tsx                 |   2 +-
 src/client/views/search/SearchBox.tsx              |  15 ++-
 src/client/views/selectedDoc/SelectedDocView.tsx   |   6 +-
 src/client/views/topbar/TopBar.tsx                 |   4 +-
 src/client/views/webcam/DashWebRTCVideo.tsx        |   5 +-
 src/debug/Repl.tsx                                 |  10 +-
 src/debug/Viewer.tsx                               |  18 ++--
 src/fields/CursorField.ts                          |   7 +-
 src/fields/Doc.ts                                  |   4 +-
 src/fields/List.ts                                 |   8 +-
 src/fields/Proxy.ts                                |  12 +--
 src/fields/util.ts                                 |   4 +-
 src/mobile/ImageUpload.tsx                         |   6 +-
 src/mobile/MobileInkOverlay.tsx                    |   2 +-
 src/mobile/MobileInterface.tsx                     | 110 ++++++++++----------
 src/typings/index.d.ts                             |   4 +-
 test/test.ts                                       | 106 ++++++++++---------
 116 files changed, 650 insertions(+), 793 deletions(-)

(limited to 'src/client/util/CalendarManager.tsx')

diff --git a/src/Utils.ts b/src/Utils.ts
index a060e4a2c..b5c218e01 100644
--- a/src/Utils.ts
+++ b/src/Utils.ts
@@ -1,13 +1,12 @@
-import * as uuid from 'uuid';
 import { ColorResult } from 'react-color';
+import * as uuid from 'uuid';
 //import { Socket } from '../node_modules/socket.io-client';
-import { Socket } from '../node_modules/socket.io/dist/index';
+import * as Color from 'color';
 import * as rp from 'request-promise';
+import { Socket } from '../node_modules/socket.io/dist/index';
 import { DocumentType } from './client/documents/DocumentTypes';
 import { Colors } from './client/views/global/globalEnums';
 import { Message } from './server/Message';
-import * as Color from 'color';
-import { action } from 'mobx';
 
 export namespace Utils {
     export let CLICK_TIME = 300;
@@ -896,23 +895,19 @@ export function setupMoveUpEvents(
     document.addEventListener('click', _clickEvent, true);
 }
 
-export function dateRangeStrToDates (dateStr: string) {
+export function dateRangeStrToDates(dateStr: string) {
     // dateStr in yyyy-mm-dd format
-    const dateRangeParts = dateStr.split("|"); // splits into from and to date
-    const fromParts = dateRangeParts[0].split("-");
-    const toParts = dateRangeParts[1].split("-");
+    const dateRangeParts = dateStr.split('|'); // splits into from and to date
+    const fromParts = dateRangeParts[0].split('-');
+    const toParts = dateRangeParts[1].split('-');
 
     const fromYear = parseInt(fromParts[0]);
-    const fromMonth = parseInt(fromParts[1])-1;
+    const fromMonth = parseInt(fromParts[1]) - 1;
     const fromDay = parseInt(fromParts[2]);
 
     const toYear = parseInt(toParts[0]);
-    const toMonth = parseInt(toParts[1])-1;
+    const toMonth = parseInt(toParts[1]) - 1;
     const toDay = parseInt(toParts[2]);
 
-
-    return [
-        new Date(fromYear, fromMonth, fromDay),
-        new Date(toYear, toMonth, toDay)
-    ];
-}
\ No newline at end of file
+    return [new Date(fromYear, fromMonth, fromDay), new Date(toYear, toMonth, toDay)];
+}
diff --git a/src/client/util/CalendarManager.tsx b/src/client/util/CalendarManager.tsx
index 6ef2d3429..6e9094b3a 100644
--- a/src/client/util/CalendarManager.tsx
+++ b/src/client/util/CalendarManager.tsx
@@ -1,26 +1,24 @@
-import * as React from 'react';
-import './CalendarManager.scss';
+import { TextField } from '@mui/material';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
-import { action, computed, observable, runInAction, makeObservable } from 'mobx';
+import * as React from 'react';
+import Select from 'react-select';
 import { Doc, DocListCast } from '../../fields/Doc';
-import { DocumentView } from '../views/nodes/DocumentView';
+import { DocData } from '../../fields/DocSymbols';
+import { StrCast } from '../../fields/Types';
 import { DictationOverlay } from '../views/DictationOverlay';
-import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
 import { MainViewModal } from '../views/MainViewModal';
-import { TextField } from '@mui/material';
-import Select from 'react-select';
-import { SettingsManager } from './SettingsManager';
-import { DateCast, DocCast, StrCast } from '../../fields/Types';
-import { SelectionManager } from './SelectionManager';
+import { DocumentView } from '../views/nodes/DocumentView';
+import { TaskCompletionBox } from '../views/nodes/TaskCompletedBox';
+import './CalendarManager.scss';
 import { DocumentManager } from './DocumentManager';
-import { DocData } from '../../fields/DocSymbols';
+import { SelectionManager } from './SelectionManager';
+import { SettingsManager } from './SettingsManager';
 // import { DateRange, Range, RangeKeyDict } from 'react-date-range';
-import { Button } from 'browndash-components';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Provider, defaultTheme } from '@adobe/react-spectrum';
-import { DateValue } from '@internationalized/date';
-import { DateRangePicker, SpectrumDateRangePickerProps } from '@adobe/react-spectrum';
+import { DateRangePicker, Provider, defaultTheme } from '@adobe/react-spectrum';
 import { IconLookup, faPlus } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Button } from 'browndash-components';
 import { Docs } from '../documents/Documents';
 import { ObservableReactComponent } from '../views/ObservableReactComponent';
 // import 'react-date-range/dist/styles.css';
@@ -51,8 +49,8 @@ const formatCalendarDateToString = (calendarDate: any) => {
 export class CalendarManager extends ObservableReactComponent<{}> {
     public static Instance: CalendarManager;
     @observable private isOpen = false;
-    @observable private targetDoc: Doc | undefined; // the target document
-    @observable private targetDocView: DocumentView | undefined; // the DocumentView of the target doc
+    @observable private targetDoc: Doc | undefined = undefined; // the target document
+    @observable private targetDocView: DocumentView | undefined = undefined; // the DocumentView of the target doc
     @observable private dialogueBoxOpacity = 1; // for the modal
     @observable private overlayOpacity = 0.4; // for the modal
 
diff --git a/src/client/util/CaptureManager.tsx b/src/client/util/CaptureManager.tsx
index 071fc1ee9..c1e0a5b2e 100644
--- a/src/client/util/CaptureManager.tsx
+++ b/src/client/util/CaptureManager.tsx
@@ -15,7 +15,7 @@ import { SelectionManager } from './SelectionManager';
 export class CaptureManager extends React.Component<{}> {
     public static Instance: CaptureManager;
     static _settingsStyle = addStyleSheet();
-    @observable _document: any;
+    @observable _document: any = undefined;
     @observable isOpen: boolean = false; // whether the CaptureManager is to be displayed or not.
 
     constructor(props: {}) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index c1d74c398..3f28f44fc 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -1,5 +1,6 @@
 import { observable, reaction, runInAction } from "mobx";
 import * as rp from 'request-promise';
+import { OmitKeys, Utils } from "../../Utils";
 import { Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
 import { InkTool } from "../../fields/InkField";
 import { List } from "../../fields/List";
@@ -8,29 +9,28 @@ import { RichTextField } from "../../fields/RichTextField";
 import { listSpec } from "../../fields/Schema";
 import { ScriptField } from "../../fields/ScriptField";
 import { Cast, DateCast, DocCast, StrCast } from "../../fields/Types";
-import { nullAudio, WebField } from "../../fields/URLField";
+import { WebField, nullAudio } from "../../fields/URLField";
 import { SetCachedGroups, SharingPermissions } from "../../fields/util";
 import { GestureUtils } from "../../pen-gestures/GestureUtils";
-import { OmitKeys, Utils } from "../../Utils";
 import { DocServer } from "../DocServer";
-import { Docs, DocumentOptions, DocUtils, FInfo } from "../documents/Documents";
 import { CollectionViewType, DocumentType } from "../documents/DocumentTypes";
-import { TreeViewType } from "../views/collections/CollectionTreeView";
+import { DocUtils, Docs, DocumentOptions, FInfo } from "../documents/Documents";
 import { DashboardView } from "../views/DashboardView";
+import { OverlayView } from "../views/OverlayView";
+import { TreeViewType } from "../views/collections/CollectionTreeView";
 import { Colors } from "../views/global/globalEnums";
 import { media_state } from "../views/nodes/AudioBox";
-import { DocumentView, OpenWhere } from "../views/nodes/DocumentView";
+import { OpenWhere } from "../views/nodes/DocumentView";
 import { ButtonType } from "../views/nodes/FontIconBox/FontIconBox";
 import { ImportElementBox } from "../views/nodes/importBox/ImportElementBox";
-import { OverlayView } from "../views/OverlayView";
 import { DragManager, dropActionType } from "./DragManager";
 import { MakeTemplate } from "./DropConverter";
 import { FollowLinkScript } from "./LinkFollower";
 import { LinkManager } from "./LinkManager";
 import { ScriptingGlobals } from "./ScriptingGlobals";
 import { ColorScheme } from "./SettingsManager";
-import { UndoManager } from "./UndoManager";
 import { SnappingManager } from "./SnappingManager";
+import { UndoManager } from "./UndoManager";
 
 interface Button {
     // DocumentOptions fields a button can set
diff --git a/src/client/util/GroupManager.tsx b/src/client/util/GroupManager.tsx
index 90f65b648..f4f879208 100644
--- a/src/client/util/GroupManager.tsx
+++ b/src/client/util/GroupManager.tsx
@@ -33,7 +33,7 @@ export class GroupManager extends ObservableReactComponent<{}> {
     @observable isOpen: boolean = false; // whether the GroupManager is to be displayed or not.
     @observable private users: string[] = []; // list of users populated from the database.
     @observable private selectedUsers: UserOptions[] | null = null; // list of users selected in the "Select users" dropdown.
-    @observable currentGroup: Opt<Doc>; // the currently selected group.
+    @observable currentGroup: Opt<Doc> = undefined; // the currently selected group.
     @observable private createGroupModalOpen: boolean = false;
     private inputRef: React.RefObject<HTMLInputElement> = React.createRef(); // the ref for the input box.
     private createGroupButtonRef: React.RefObject<HTMLButtonElement> = React.createRef(); // the ref for the group creation button
diff --git a/src/client/util/HypothesisUtils.ts b/src/client/util/HypothesisUtils.ts
index 990798ed3..0ae23d793 100644
--- a/src/client/util/HypothesisUtils.ts
+++ b/src/client/util/HypothesisUtils.ts
@@ -1,16 +1,15 @@
-import { StrCast, Cast } from '../../fields/Types';
-import { SearchUtil } from './SearchUtil';
 import { action, runInAction } from 'mobx';
+import { simulateMouseClick } from '../../Utils';
 import { Doc, Opt } from '../../fields/Doc';
+import { Cast, StrCast } from '../../fields/Types';
+import { WebField } from '../../fields/URLField';
 import { DocumentType } from '../documents/DocumentTypes';
 import { Docs } from '../documents/Documents';
-import { SelectionManager } from './SelectionManager';
-import { WebField } from '../../fields/URLField';
-import { DocumentManager } from './DocumentManager';
 import { DocumentLinksButton } from '../views/nodes/DocumentLinksButton';
-import { simulateMouseClick, Utils } from '../../Utils';
 import { DocumentView } from '../views/nodes/DocumentView';
-import { Id } from '../../fields/FieldSymbols';
+import { DocumentManager } from './DocumentManager';
+import { SearchUtil } from './SearchUtil';
+import { SelectionManager } from './SelectionManager';
 
 export namespace Hypothesis {
     /**
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index f0887676f..3938b81cd 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -40,14 +40,9 @@ export class DocumentButtonBar extends ObservableReactComponent<{ views: () => (
     private _pullAnimating = false;
     private _pushAnimating = false;
     private _pullColorAnimating = false;
-    @observable private pushIcon: IconProp = 'arrow-alt-circle-up';
-    @observable private pullIcon: IconProp = 'arrow-alt-circle-down';
-    @observable private pullColor: string = 'white';
     @observable public isAnimatingFetch = false;
     @observable public isAnimatingPulse = false;
 
-    @observable private openHover: UtilityButtonState = UtilityButtonState.Default;
-
     @observable public static Instance: DocumentButtonBar;
     public static hasPushedHack = false;
     public static hasPulledHack = false;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d2f23c2f3..dab6e6193 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -12,7 +12,7 @@ import { RichTextField } from '../../fields/RichTextField';
 import { ScriptField } from '../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../fields/Types';
 import { GetEffectiveAcl } from '../../fields/util';
-import { emptyFunction, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
+import { emptyFunction, lightOrDark, numberValue, returnFalse, setupMoveUpEvents, Utils } from '../../Utils';
 import { Docs } from '../documents/Documents';
 import { DocumentType } from '../documents/DocumentTypes';
 import { DocumentManager } from '../util/DocumentManager';
@@ -85,7 +85,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
     }
 
     @computed get ClippedBounds() {
-        const bounds = this.Bounds;
+        const bounds = { ...this.Bounds };
         const leftBounds = this._props.boundsLeft;
         const topBounds = LightboxView.LightboxDoc ? 0 : this._props.boundsTop;
         bounds.x = Math.max(leftBounds, bounds.x - this._resizeBorderWidth / 2) + this._resizeBorderWidth / 2;
@@ -106,9 +106,8 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                             : { x: Math.min(rect.left, bounds.x),
                                 y: Math.min(rect.top, bounds.y),
                                 r: Math.max(rect.right, bounds.r),
-                                b: Math.max(rect.bottom, bounds.b),
-                                c: SelectionManager.Views.length === 1 ? rect.center : undefined },
-                    { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE, c: undefined as { X: number; Y: number } | undefined }); // prettier-ignore
+                                b: Math.max(rect.bottom, bounds.b)},
+                    { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); // prettier-ignore
     }
 
     @action
@@ -811,7 +810,7 @@ export class DocumentDecorations extends ObservableReactComponent<DocumentDecora
                                 <div
                                     className="documentDecorations-borderRadius"
                                     style={{
-                                        background: `${this._isRounding ? Colors.MEDIUM_BLUE : SettingsManager.userColor}`,
+                                        background: `${this._isRounding ? Colors.MEDIUM_BLUE : lightOrDark(StrCast(seldocview.layoutDoc._backgroundColor, SettingsManager.userColor))}`,
                                         transform: `translate(${radiusHandleLocation ?? 0}px, ${(radiusHandleLocation ?? 0) + (this._showNothing ? 0 : this._titleHeight)}px)`,
                                     }}
                                     onPointerDown={this.onRadiusDown}
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx
index a3c4350d9..d3075a5cd 100644
--- a/src/client/views/FilterPanel.tsx
+++ b/src/client/views/FilterPanel.tsx
@@ -1,24 +1,23 @@
-import * as React from 'react';
 import { action, computed, observable, ObservableMap } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Handles, Rail, Slider, Ticks, Tracks } from 'react-compound-slider';
 import { AiOutlineMinusSquare, AiOutlinePlusSquare } from 'react-icons/ai';
 import { CiCircleRemove } from 'react-icons/ci';
 import Select from 'react-select';
 import { Doc, DocListCast, Field, LinkedTo, StrListCast } from '../../fields/Doc';
+import { Id } from '../../fields/FieldSymbols';
+import { List } from '../../fields/List';
 import { RichTextField } from '../../fields/RichTextField';
-import { DocOptions, DocumentOptions, FInfo } from '../documents/Documents';
+import { DocOptions, FInfo } from '../documents/Documents';
 import { DocumentManager } from '../util/DocumentManager';
 import { UserOptions } from '../util/GroupManager';
 import { SearchUtil } from '../util/SearchUtil';
+import { SettingsManager } from '../util/SettingsManager';
 import { undoable } from '../util/UndoManager';
 import './FilterPanel.scss';
 import { FieldView } from './nodes/FieldView';
 import { Handle, Tick, TooltipRail, Track } from './nodes/SliderBox-components';
-import { SettingsManager } from '../util/SettingsManager';
-import { Id } from '../../fields/FieldSymbols';
-import { List } from '../../fields/List';
-import { emptyFunction } from '../../Utils';
 
 interface filterProps {
     Document: Doc;
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx
index 33cda6a62..65aadc148 100644
--- a/src/client/views/GestureOverlay.tsx
+++ b/src/client/views/GestureOverlay.tsx
@@ -1,15 +1,14 @@
-import * as React from 'react';
 import * as fitCurve from 'fit-curve';
-import { action, computed, makeObservable, observable, runInAction, toJS } from 'mobx';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../Utils';
+import * as React from 'react';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, setupMoveUpEvents } from '../../Utils';
 import { Doc, Opt } from '../../fields/Doc';
 import { InkData, InkTool } from '../../fields/InkField';
 import { BoolCast, NumCast } from '../../fields/Types';
 import MobileInkOverlay from '../../mobile/MobileInkOverlay';
 import { GestureUtils } from '../../pen-gestures/GestureUtils';
 import { MobileInkOverlayContent } from '../../server/Message';
-import { CognitiveServices } from '../cognitive_services/CognitiveServices';
 import { InteractionUtils } from '../util/InteractionUtils';
 import { ScriptingGlobals } from '../util/ScriptingGlobals';
 import { Transform } from '../util/Transform';
@@ -29,9 +28,9 @@ import {
     SetActiveInkColor,
     SetActiveInkWidth,
 } from './InkingStroke';
+import { ObservableReactComponent } from './ObservableReactComponent';
 import { checkInksToGroup } from './global/globalScripts';
 import { DocumentView } from './nodes/DocumentView';
-import { ObservableReactComponent } from './ObservableReactComponent';
 
 interface GestureOverlayProps {
     isActive: boolean;
@@ -48,22 +47,22 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil
         return BoolCast(Doc.UserDoc().recognizeGestures);
     }
 
-    @observable public InkShape: Opt<GestureUtils.Gestures>;
-    @observable public SavedColor?: string;
-    @observable public SavedWidth?: number;
+    @observable public InkShape: Opt<GestureUtils.Gestures> = undefined;
+    @observable public SavedColor?: string = undefined;
+    @observable public SavedWidth?: number = undefined;
     @observable public Tool: ToolglassTools = ToolglassTools.None;
     @observable public KeepPrimitiveMode = false; // for whether primitive selection enters a one-shot or persistent mode
 
-    @observable private _thumbX?: number;
-    @observable private _thumbY?: number;
+    @observable private _thumbX?: number = undefined;
+    @observable private _thumbY?: number = undefined;
     @observable private _selectedIndex: number = -1;
     @observable private _menuX: number = -300;
     @observable private _menuY: number = -300;
-    @observable private _pointerY?: number;
+    @observable private _pointerY?: number = undefined;
     @observable private _points: { X: number; Y: number }[] = [];
     @observable private _strokes: InkData[] = [];
-    @observable private _palette?: JSX.Element;
-    @observable private _clipboardDoc?: JSX.Element;
+    @observable private _palette?: JSX.Element = undefined;
+    @observable private _clipboardDoc?: JSX.Element = undefined;
     @observable private _possibilities: JSX.Element[] = [];
 
     public static DownDocView: DocumentView | undefined;
diff --git a/src/client/views/InkTranscription.tsx b/src/client/views/InkTranscription.tsx
index b2ac208ca..7e2b334af 100644
--- a/src/client/views/InkTranscription.tsx
+++ b/src/client/views/InkTranscription.tsx
@@ -17,10 +17,10 @@
 // export class InkTranscription extends React.Component {
 //     static Instance: InkTranscription;
 
-//     @observable _mathRegister: any;
-//     @observable _mathRef: any;
-//     @observable _textRegister: any;
-//     @observable _textRef: any;
+//     @observable _mathRegister: any= undefined;
+//     @observable _mathRef: any= undefined;
+//     @observable _textRegister: any= undefined;
+//     @observable _textRef: any= undefined;
 //     private lastJiix: any;
 //     private currGroup?: Doc;
 
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index 9c96b4563..95c677845 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -20,9 +20,9 @@
     
     Most of the operations that can be performed on an InkStroke (eg delete a point, rotate, stretch) are implemented in the InkStrokeProperties helper class
 */
-import * as React from 'react';
 import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../fields/Doc';
 import { InkData, InkField } from '../../fields/InkField';
 import { BoolCast, Cast, NumCast, RTFCast, StrCast } from '../../fields/Types';
@@ -32,7 +32,6 @@ import { CognitiveServices } from '../cognitive_services/CognitiveServices';
 import { Docs } from '../documents/Documents';
 import { InteractionUtils } from '../util/InteractionUtils';
 import { SnappingManager } from '../util/SnappingManager';
-import { Transform } from '../util/Transform';
 import { UndoManager } from '../util/UndoManager';
 import { ContextMenu } from './ContextMenu';
 import { ViewBoxBaseComponent } from './DocComponent';
@@ -59,14 +58,14 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
     private _handledClick = false; // flag denoting whether ink stroke has handled a psuedo-click onPointerUp so that the real onClick event can be stopPropagated
     private _disposers: { [key: string]: IReactionDisposer } = {};
 
-    @observable _nearestSeg?: number; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight)
-    @observable _nearestT?: number; // nearest t value within the nearest Bezier segment "
+    @observable _nearestSeg?: number = undefined; // nearest Bezier segment along the ink stroke to the cursor (used for displaying the Add Point highlight)
+    @observable _nearestT?: number = undefined; // nearest t value within the nearest Bezier segment "
     @observable _nearestScrPt?: { X: number; Y: number }; // nearst screen point on the ink stroke ""
 
     componentDidMount() {
-        this.props.setContentView?.(this);
+        this._props.setContentView?.(this);
         this._disposers.selfDisper = reaction(
-            () => this.props.isSelected(), // react to stroke being deselected by turning off ink handles
+            () => this._props.isSelected(), // react to stroke being deselected by turning off ink handles
             selected => !selected && (InkStrokeProperties.Instance._controlButton = false)
         );
     }
@@ -76,7 +75,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
 
     // transform is the inherited screentolocal xf plus any scaling that was done to make the stroke
     // fit within its panel (e.g., for content fitting views like Lightbox or multicolumn, etc)
-    screenToLocal = () => this.props.ScreenToLocalTransform().scale(this.props.NativeDimScaling?.() || 1);
+    screenToLocal = () => this._props.ScreenToLocalTransform().scale(this._props.NativeDimScaling?.() || 1);
 
     getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
         const subAnchor = this._subContentView?.getAnchor?.(addAsAnnotation);
@@ -100,27 +99,6 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
         return this.Document;
     };
 
-    /**
-     * @returns the center of the ink stroke in the ink document's coordinate space (not screen space, and not the ink data coordinate space);
-     * DocumentDecorations calls getBounds() on DocumentViews which call getCenter() if defined - in the case of ink it needs to be defined since
-     * the center of the ink stroke changes as the stroke is rotated.
-     */
-    getCenter = (xf: Transform) => {
-        const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData();
-        const angle = -NumCast(this.layoutDoc.rotation);
-        const newPoints = inkData.map(pt => {
-            const newX = Math.cos(angle) * pt.X - (Math.sin(angle) * pt.Y * inkScaleY) / inkScaleX;
-            const newY = (Math.sin(angle) * pt.X * inkScaleX) / inkScaleY + Math.cos(angle) * pt.Y;
-            return { X: newX, Y: newY };
-        });
-        const crx = (Math.max(...newPoints.map(np => np.X)) + Math.min(...newPoints.map(np => np.X))) / 2;
-        const cry = (Math.max(...newPoints.map(np => np.Y)) + Math.min(...newPoints.map(np => np.Y))) / 2;
-        const cx = Math.cos(-angle) * crx - (Math.sin(-angle) * cry * inkScaleY) / inkScaleX;
-        const cy = (Math.sin(-angle) * crx * inkScaleX) / inkScaleY + Math.cos(-angle) * cry;
-        const tc = xf.transformPoint((cx - inkLeft - inkStrokeWidth / 2) * inkScaleX + inkStrokeWidth / 2, (cy - inkTop - inkStrokeWidth / 2) * inkScaleY + inkStrokeWidth / 2);
-        return { X: tc[0], Y: tc[1] };
-    };
-
     /**
      * analyzes the ink stroke and saves the analysis of the stroke to the 'inkAnalysis' field,
      * and the recognized words to the 'handwriting'
@@ -147,7 +125,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
     @action
     onPointerDown = (e: React.PointerEvent) => {
         this._handledClick = false;
-        const inkView = this.props.docViewPath().lastElement();
+        const inkView = this._props.docViewPath().lastElement();
         const { inkData, inkScaleX, inkScaleY, inkStrokeWidth, inkTop, inkLeft } = this.inkScaledData();
         const screenPts = inkData
             .map(point =>
@@ -159,7 +137,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
         const { nearestSeg } = InkStrokeProperties.nearestPtToStroke(screenPts, { X: e.clientX, Y: e.clientY });
         const controlIndex = nearestSeg;
         const wasSelected = InkStrokeProperties.Instance._currentPoint === controlIndex;
-        const isEditing = InkStrokeProperties.Instance._controlButton && this.props.isSelected();
+        const isEditing = InkStrokeProperties.Instance._controlButton && this._props.isSelected();
         this.controlUndo = undefined;
         setupMoveUpEvents(
             this,
@@ -187,7 +165,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
                     InkStrokeProperties.Instance._currentPoint = -1;
                     this._handledClick = true; // mark the double-click pseudo pointerevent so we can block the real mouse event from propagating to DocumentView
                     if (isEditing) {
-                        this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this.props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice());
+                        this._nearestT && this._nearestSeg !== undefined && InkStrokeProperties.Instance.addPoints(this._props.docViewPath().lastElement(), this._nearestT, this._nearestSeg, this.inkScaledData().inkData.slice());
                     }
                 }
             }),
@@ -258,8 +236,8 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
             inkLeft,
             inkWidth,
             inkHeight,
-            inkScaleX: (this.props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1,
-            inkScaleY: (this.props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1,
+            inkScaleX: (this._props.PanelWidth() - inkStrokeWidth) / (inkWidth - inkStrokeWidth || 1) || 1,
+            inkScaleY: (this._props.PanelHeight() - inkStrokeWidth) / (inkHeight - inkStrokeWidth || 1) || 1,
         };
     };
 
@@ -311,7 +289,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
      * @returns the JSX controls for displaying an editing UI for the stroke (control point & tangent handles)
      */
     componentUI = (boundsLeft: number, boundsTop: number) => {
-        const inkDoc = this.props.Document;
+        const inkDoc = this.Document;
         const { inkData, inkStrokeWidth } = this.inkScaledData();
         const screenSpaceCenterlineStrokeWidth = Math.min(3, inkStrokeWidth * this.screenToLocal().inverse().Scale); // the width of the blue line widget that shows the centerline of the ink stroke
 
@@ -321,7 +299,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
         const endMarker = StrCast(this.layoutDoc.stroke_endMarker);
         const markerScale = NumCast(this.layoutDoc.stroke_markerScale);
         return SnappingManager.IsDragging ? null : !InkStrokeProperties.Instance._controlButton ? (
-            !this.props.isSelected() || InkingStroke.IsClosed(inkData) ? null : (
+            !this._props.isSelected() || InkingStroke.IsClosed(inkData) ? null : (
                 <div className="inkstroke-UI" style={{ clip: `rect(${boundsTop}px, 10000px, 10000px, ${boundsLeft}px)` }}>
                     <InkEndPtHandles inkView={this} inkDoc={inkDoc} startPt={this.startPt} endPt={this.endPt} screenSpaceLineWidth={screenSpaceCenterlineStrokeWidth} />
                 </div>
@@ -360,12 +338,12 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
     setSubContentView = (doc: DocComponentView) => (this._subContentView = doc);
     @computed get fillColor() {
         const isInkMask = BoolCast(this.layoutDoc.stroke_isInkMask);
-        return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FillColor) ?? 'transparent';
+        return isInkMask ? DashColor(StrCast(this.layoutDoc.fillColor, 'transparent')).blacken(0).rgb().toString() : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FillColor) ?? 'transparent';
     }
     @computed get strokeColor() {
         const { inkData } = this.inkScaledData();
         const fillColor = this.fillColor;
-        return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
+        return !InkingStroke.IsClosed(inkData) && fillColor && fillColor !== 'transparent' ? fillColor : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color) ?? StrCast(this.layoutDoc.color);
     }
     render() {
         TraceMobx();
@@ -385,9 +363,9 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
                 this.layoutDoc._height = Math.round(NumCast(this.layoutDoc._height));
             });
         }
-        const highlight = !this.controlUndo && this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Highlighting);
+        const highlight = !this.controlUndo && this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Highlighting);
         const highlightIndex = highlight?.highlightIndex;
-        const highlightColor = !this.props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined;
+        const highlightColor = !this._props.isSelected() && !isInkMask && highlight?.highlightIndex ? highlight?.highlightColor : undefined;
         const color = StrCast(this.layoutDoc.stroke_outlineColor, !closed && fillColor && fillColor !== 'transparent' ? StrCast(this.layoutDoc.color, 'transparent') : 'transparent');
 
         // Visually renders the polygonal line made by the user.
@@ -437,7 +415,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
                 inkScaleX,
                 inkScaleY,
                 '',
-                this.props.pointerEvents?.() ?? 'visiblepainted',
+                this._props.pointerEvents?.() ?? 'visiblepainted',
                 0.0,
                 false,
                 downHdlr,
@@ -450,7 +428,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
         const lineHeightGuess = +getComputedStyle(document.body).lineHeight.replace('px', '') / +getComputedStyle(document.body).fontSize.replace('px', '');
         const interactions = {
             onPointerLeave: action(() => (this._nearestScrPt = undefined)),
-            onPointerMove: this.props.isSelected() ? this.onPointerMove : undefined,
+            onPointerMove: this._props.isSelected() ? this.onPointerMove : undefined,
             onClick: (e: React.MouseEvent) => this._handledClick && e.stopPropagation(),
             onContextMenu: () => {
                 const cm = ContextMenu.Instance;
@@ -464,27 +442,27 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
                 <svg
                     className="inkStroke"
                     style={{
-                        transform: isInkMask ? `rotate(-${NumCast(this.props.CollectionFreeFormDocumentView?.()._props.w_Rotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
+                        transform: isInkMask ? `rotate(-${NumCast(this._props.CollectionFreeFormDocumentView?.()._props.w_Rotation?.() ?? 0)}deg) translate(${InkingStroke.MaskDim / 2}px, ${InkingStroke.MaskDim / 2}px)` : undefined,
                         // mixBlendMode: this.layoutDoc.tool === InkTool.Highlighter ? 'multiply' : 'unset',
-                        cursor: this.props.isSelected() ? 'default' : undefined,
+                        cursor: this._props.isSelected() ? 'default' : undefined,
                     }}
                     {...interactions}>
                     {clickableLine(this.onPointerDown, isInkMask)}
                     {isInkMask ? null : inkLine}
                 </svg>
-                {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this.props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
+                {!closed || (!RTFCast(this.dataDoc.text)?.Text && (!this._props.isSelected() || Doc.UserDoc().activeInkHideTextLabels)) ? null : (
                     <div
                         className="inkStroke-text"
                         style={{
                             color: StrCast(this.layoutDoc.textColor, 'black'),
-                            pointerEvents: this.props.isDocumentActive?.() ? 'all' : undefined,
+                            pointerEvents: this._props.isDocumentActive?.() ? 'all' : undefined,
                             width: NumCast(this.layoutDoc._width),
-                            transform: `scale(${this.props.NativeDimScaling?.() || 1})`,
+                            transform: `scale(${this._props.NativeDimScaling?.() || 1})`,
                             transformOrigin: 'top left',
-                            //top: (this.props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this.props.NativeDimScaling?.() || 1)) / 2,
+                            //top: (this._props.PanelHeight() - (lineHeightGuess * fsize + 20) * (this._props.NativeDimScaling?.() || 1)) / 2,
                         }}>
                         <FormattedTextBox
-                            {...this.props}
+                            {...this._props}
                             setHeight={undefined}
                             setContentView={this.setSubContentView} // this makes the inkingStroke the "dominant" component - ie, it will show the inking UI when selected (not text)
                             yPadding={10}
@@ -493,7 +471,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps>() {
                             dontRegisterView={true}
                             noSidebar={true}
                             dontScale={true}
-                            isContentActive={this.props.isContentActive}
+                            isContentActive={this._props.isContentActive}
                         />
                     </div>
                 )}
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 094bd2adb..35ffab337 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -118,7 +118,7 @@ export class MainView extends ObservableReactComponent<{}> {
     @computed private get userDoc() {
         return Doc.UserDoc();
     }
-    @observable mainDoc: Opt<Doc>;
+    @observable mainDoc: Opt<Doc> = undefined;
     @computed private get mainContainer() {
         if (window.location.pathname.startsWith('/doc/') && Doc.CurrentUserEmail === 'guest') {
             DocServer.GetRefField(window.location.pathname.substring('/doc/'.length)).then(main => runInAction(() => (this.mainDoc = main as Doc)));
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 5c6912121..89c3c41f8 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -1,12 +1,12 @@
-import * as React from 'react';
-import './MetadataEntryMenu.scss';
+import { IReactionDisposer, action, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
-import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx';
-import { KeyValueBox } from './nodes/KeyValueBox';
-import { Doc, Field, DocListCastAsync, DocListCast } from '../../fields/Doc';
+import * as React from 'react';
 import * as Autosuggest from 'react-autosuggest';
-import { undoBatch, UndoManager } from '../util/UndoManager';
 import { emptyFunction, emptyPath } from '../../Utils';
+import { Doc, DocListCast, Field } from '../../fields/Doc';
+import { undoBatch } from '../util/UndoManager';
+import './MetadataEntryMenu.scss';
+import { KeyValueBox } from './nodes/KeyValueBox';
 
 export type DocLike = Doc | Doc[] | Promise<Doc> | Promise<Doc[]>;
 export interface MetadataEntryProps {
diff --git a/src/client/views/PreviewCursor.tsx b/src/client/views/PreviewCursor.tsx
index 166afc0c2..a69a5f5e8 100644
--- a/src/client/views/PreviewCursor.tsx
+++ b/src/client/views/PreviewCursor.tsx
@@ -24,7 +24,7 @@ export class PreviewCursor extends ObservableReactComponent<{}> {
     _addLiveTextDoc?: (doc: Doc) => void;
     _nudge?: undefined | ((x: number, y: number) => boolean);
     _slowLoadDocuments?: (files: File[] | string, options: DocumentOptions, generatedDocuments: Doc[], text: string, completed: ((doc: Doc[]) => void) | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => Promise<void>;
-    @observable _clickPoint: number[];
+    @observable _clickPoint: number[] = [];
     @observable public Visible = false;
     public Doc: Opt<Doc>;
     constructor(props: any) {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 8540e81e1..f1dadcd5e 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -2,6 +2,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Dropdown, DropdownType, IListItemProps, Toggle, ToggleType, Type } from 'browndash-components';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { AiOutlineColumnWidth } from 'react-icons/ai';
 import { BiHide, BiShow } from 'react-icons/bi';
 import { BsGrid3X3GapFill } from 'react-icons/bs';
@@ -12,28 +13,20 @@ import { RxWidth } from 'react-icons/rx';
 import { TbEditCircle, TbEditCircleOff, TbHandOff, TbHandStop, TbHighlight, TbHighlightOff } from 'react-icons/tb';
 import { TfiBarChart } from 'react-icons/tfi';
 import { Doc, DocListCast, Opt } from '../../fields/Doc';
-import { InkField } from '../../fields/InkField';
 import { RichTextField } from '../../fields/RichTextField';
 import { BoolCast, ScriptCast } from '../../fields/Types';
 import { ImageField } from '../../fields/URLField';
-import { DocUtils } from '../documents/Documents';
 import { CollectionViewType, DocumentType } from '../documents/DocumentTypes';
+import { DocUtils } from '../documents/Documents';
 import { IsFollowLinkScript } from '../util/LinkFollower';
 import { LinkManager } from '../util/LinkManager';
 import { SelectionManager } from '../util/SelectionManager';
 import { SettingsManager } from '../util/SettingsManager';
-import { undoable, undoBatch } from '../util/UndoManager';
-import { Colors } from './global/globalEnums';
+import { undoBatch, undoable } from '../util/UndoManager';
 import { InkingStroke } from './InkingStroke';
-import { DocumentView, OpenWhere } from './nodes/DocumentView';
 import './PropertiesButtons.scss';
-import * as React from 'react';
-
-enum UtilityButtonState {
-    Default,
-    OpenRight,
-    OpenExternally,
-}
+import { Colors } from './global/globalEnums';
+import { DocumentView, OpenWhere } from './nodes/DocumentView';
 
 @observer
 export class PropertiesButtons extends React.Component<{}, {}> {
diff --git a/src/client/views/PropertiesDocBacklinksSelector.tsx b/src/client/views/PropertiesDocBacklinksSelector.tsx
index 58d3b72e8..244cd4aa0 100644
--- a/src/client/views/PropertiesDocBacklinksSelector.tsx
+++ b/src/client/views/PropertiesDocBacklinksSelector.tsx
@@ -7,10 +7,10 @@ import { DocumentType } from '../documents/DocumentTypes';
 import { LinkManager } from '../util/LinkManager';
 import { SelectionManager } from '../util/SelectionManager';
 import { SettingsManager } from '../util/SettingsManager';
+import './PropertiesDocBacklinksSelector.scss';
 import { CollectionDockingView } from './collections/CollectionDockingView';
 import { LinkMenu } from './linking/LinkMenu';
-import { OpenWhere, OpenWhereMod } from './nodes/DocumentView';
-import './PropertiesDocBacklinksSelector.scss';
+import { OpenWhere } from './nodes/DocumentView';
 
 type PropertiesDocBacklinksSelectorProps = {
     Document: Doc;
diff --git a/src/client/views/PropertiesSection.tsx b/src/client/views/PropertiesSection.tsx
index 2b9bfb505..3c9fa1123 100644
--- a/src/client/views/PropertiesSection.tsx
+++ b/src/client/views/PropertiesSection.tsx
@@ -1,11 +1,9 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import './PropertiesSection.scss';
-import { Doc } from '../../fields/Doc';
-import { StrCast } from '../../fields/Types';
+import * as React from 'react';
 import { SettingsManager } from '../util/SettingsManager';
+import './PropertiesSection.scss';
 
 export interface PropertiesSectionProps {
     title: string;
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 48653f30a..791928b4a 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -1,5 +1,6 @@
 import { action, computed, observable, ObservableSet, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc, DocListCast } from '../../fields/Doc';
 import { ScriptField } from '../../fields/ScriptField';
 import { Cast, StrCast } from '../../fields/Types';
@@ -13,7 +14,6 @@ import { CollectionTreeView } from './collections/CollectionTreeView';
 import { DocumentView } from './nodes/DocumentView';
 import { DefaultStyleProvider } from './StyleProvider';
 import './TemplateMenu.scss';
-import * as React from 'react';
 
 @observer
 class TemplateToggle extends React.Component<{ template: string; checked: boolean; toggle: (event: React.ChangeEvent<HTMLInputElement>, template: string) => void }> {
diff --git a/src/client/views/UndoStack.tsx b/src/client/views/UndoStack.tsx
index f07e38af1..ea038250e 100644
--- a/src/client/views/UndoStack.tsx
+++ b/src/client/views/UndoStack.tsx
@@ -15,8 +15,8 @@ interface UndoStackProps {
 }
 @observer
 export class UndoStack extends React.Component<UndoStackProps> {
-    @observable static HideInline: boolean;
-    @observable static Expand: boolean;
+    @observable static HideInline: boolean = false;
+    @observable static Expand: boolean = false;
     render() {
         const background = UndoManager.batchCounter.get() ? 'yellow' : SettingsManager.userVariantColor;
         const color = UndoManager.batchCounter.get() ? 'black' : SettingsManager.userColor;
@@ -39,19 +39,25 @@ export class UndoStack extends React.Component<UndoStackProps> {
                                         color,
                                     }}>
                                     {Array.from(UndoManager.undoStackNames).map((name, i) => (
-                                        <div className="undoStack-resultContainer" key={i} 
-                                             onClick={e => {
+                                        <div
+                                            className="undoStack-resultContainer"
+                                            key={i}
+                                            onClick={e => {
                                                 const size = UndoManager.undoStackNames.length;
-                                                for (let n = 0; n < size-i; n++ ) UndoManager.Undo();  } } 
-                                            >
+                                                for (let n = 0; n < size - i; n++) UndoManager.Undo();
+                                            }}>
                                             <div className="undoStack-commandString">{StrCast(name).replace(/[^\.]*\./, '')}</div>
                                         </div>
                                     ))}
                                     {Array.from(UndoManager.redoStackNames)
                                         .reverse()
                                         .map((name, i) => (
-                                            <div className="undoStack-resultContainer" key={i} onClick={e =>
-                                                { for (let n = 0; n <= i; n++ ) UndoManager.Redo() }}>
+                                            <div
+                                                className="undoStack-resultContainer"
+                                                key={i}
+                                                onClick={e => {
+                                                    for (let n = 0; n <= i; n++) UndoManager.Redo();
+                                                }}>
                                                 <div className="undoStack-commandString" style={{ fontWeight: 'bold', background: SettingsManager.userBackgroundColor, color: SettingsManager.userColor }}>
                                                     {StrCast(name).replace(/[^\.]*\./, '')}
                                                 </div>
diff --git a/src/client/views/animationtimeline/Region.tsx b/src/client/views/animationtimeline/Region.tsx
index 15cbbc16f..99163f6c6 100644
--- a/src/client/views/animationtimeline/Region.tsx
+++ b/src/client/views/animationtimeline/Region.tsx
@@ -6,11 +6,11 @@ import { List } from '../../../fields/List';
 import { createSchema, defaultSpec, listSpec, makeInterface } from '../../../fields/Schema';
 import { Cast, NumCast } from '../../../fields/Types';
 import { Transform } from '../../util/Transform';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import '../global/globalCssVariables.module.scss';
 import './Region.scss';
 import './Timeline.scss';
 import { TimelineMenu } from './TimelineMenu';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 /**
  * Useful static functions that you can use. Mostly for logic, but you can also add UI logic here also
diff --git a/src/client/views/animationtimeline/Timeline.tsx b/src/client/views/animationtimeline/Timeline.tsx
index f27a2d2fd..cc4da1694 100644
--- a/src/client/views/animationtimeline/Timeline.tsx
+++ b/src/client/views/animationtimeline/Timeline.tsx
@@ -4,17 +4,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { Utils, emptyFunction, setupMoveUpEvents } from '../../../Utils';
 import { Doc, DocListCast } from '../../../fields/Doc';
 import { BoolCast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, setupMoveUpEvents, Utils } from '../../../Utils';
 import { DocumentType } from '../../documents/DocumentTypes';
 import clamp from '../../util/clamp';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { FieldViewProps } from '../nodes/FieldView';
 import { RegionHelpers } from './Region';
 import './Timeline.scss';
 import { TimelineOverview } from './TimelineOverview';
 import { Track } from './Track';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 /**
  * Timeline class controls most of timeline functions besides individual region and track mechanism. Main functions are 
diff --git a/src/client/views/animationtimeline/TimelineOverview.tsx b/src/client/views/animationtimeline/TimelineOverview.tsx
index 82ac69a3b..928739b53 100644
--- a/src/client/views/animationtimeline/TimelineOverview.tsx
+++ b/src/client/views/animationtimeline/TimelineOverview.tsx
@@ -28,7 +28,7 @@ export class TimelineOverview extends React.Component<TimelineOverviewProps> {
     @observable private overviewBarWidth: number = 0;
     @observable private playbarWidth: number = 0;
     @observable private activeOverviewWidth: number = 0;
-    @observable private _authoringReaction?: IReactionDisposer;
+    @observable private _authoringReaction?: IReactionDisposer = undefined;
     @observable private visibleTime: number = 0;
     @observable private currentX: number = 0;
     @observable private visibleStart: number = 0;
diff --git a/src/client/views/animationtimeline/Track.tsx b/src/client/views/animationtimeline/Track.tsx
index 00aa51cac..490a14be5 100644
--- a/src/client/views/animationtimeline/Track.tsx
+++ b/src/client/views/animationtimeline/Track.tsx
@@ -8,10 +8,10 @@ import { ObjectField } from '../../../fields/ObjectField';
 import { listSpec } from '../../../fields/Schema';
 import { Cast, NumCast } from '../../../fields/Types';
 import { Transform } from '../../util/Transform';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { Region, RegionData, RegionHelpers } from './Region';
 import { Timeline } from './Timeline';
 import './Track.scss';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 interface IProps {
     timeline: Timeline;
@@ -29,9 +29,9 @@ interface IProps {
 @observer
 export class Track extends ObservableReactComponent<IProps> {
     @observable private _inner = React.createRef<HTMLDivElement>();
-    @observable private _currentBarXReaction: any;
-    @observable private _timelineVisibleReaction: any;
-    @observable private _autoKfReaction: any;
+    @observable private _currentBarXReaction: any = undefined;
+    @observable private _timelineVisibleReaction: any = undefined;
+    @observable private _autoKfReaction: any = undefined;
     @observable private _newKeyframe: boolean = false;
     private readonly MAX_TITLE_HEIGHT = 75;
     @observable private _trackHeight = 0;
diff --git a/src/client/views/collections/CollectionCalendarView.tsx b/src/client/views/collections/CollectionCalendarView.tsx
index 2cec29669..4c0a917f5 100644
--- a/src/client/views/collections/CollectionCalendarView.tsx
+++ b/src/client/views/collections/CollectionCalendarView.tsx
@@ -1,18 +1,11 @@
-import * as React from 'react';
-import { CollectionSubView } from './CollectionSubView';
+import { computed, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
-import { computed, makeObservable, observable } from 'mobx';
-import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import * as React from 'react';
+import { dateRangeStrToDates, emptyFunction, returnTrue } from '../../../Utils';
+import { Doc, DocListCast } from '../../../fields/Doc';
+import { StrCast } from '../../../fields/Types';
 import { CollectionStackingView } from './CollectionStackingView';
-import { CollectionViewType } from '../../documents/DocumentTypes';
-import { dateRangeStrToDates, emptyFunction, returnAll, returnEmptyDoclist, returnNone, returnOne, returnTrue } from '../../../Utils';
-import { DocumentView, DocumentViewProps } from '../nodes/DocumentView';
-import { TbRuler } from 'react-icons/tb';
-import { Transform } from '../../util/Transform';
-import { DocData } from '../../../fields/DocSymbols';
-import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { StyleProp } from '../StyleProvider';
-import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
+import { CollectionSubView } from './CollectionSubView';
 
 @observer
 export class CollectionCalendarView extends CollectionSubView() {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 75c178136..868df7a3b 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -1,4 +1,4 @@
-import { action, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
+import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
@@ -30,7 +30,7 @@ import { ScriptingRepl } from '../ScriptingRepl';
 import { UndoStack } from '../UndoStack';
 import './CollectionDockingView.scss';
 import { CollectionFreeFormView } from './collectionFreeForm';
-import { CollectionSubView, SubCollectionViewProps } from './CollectionSubView';
+import { CollectionSubView } from './CollectionSubView';
 import { TabDocView } from './TabDocView';
 const _global = (window /* browser */ || global) /* node */ as any;
 
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 443aa3f17..2a6cb081f 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -32,16 +32,13 @@ interface CollectionMenuProps {
 @observer
 export class CollectionMenu extends AntimodeMenu<CollectionMenuProps> {
     @observable static Instance: CollectionMenu;
-
     @observable SelectedCollection: DocumentView | undefined = undefined;
-    @observable FieldKey: string;
 
     private _docBtnRef = React.createRef<HTMLDivElement>();
 
     constructor(props: any) {
         super(props);
         makeObservable(this);
-        this.FieldKey = '';
         CollectionMenu.Instance = this;
         this._canFade = false; // don't let the inking menu fade away
         this.Pinned = Cast(Doc.UserDoc()['menuCollections-pinned'], 'boolean', true);
diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index af822d917..2aad48d4a 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -1,4 +1,4 @@
-import { action, observable, trace } from 'mobx';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { emptyFunction, setupMoveUpEvents } from '../../../Utils';
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 170b1f1ec..e5068645f 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -1,5 +1,6 @@
 import { action, computed, IReactionDisposer, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc, DocListCast } from '../../../fields/Doc';
 import { ScriptField } from '../../../fields/ScriptField';
 import { NumCast, StrCast } from '../../../fields/Types';
@@ -12,7 +13,6 @@ import { computePassLayout, computeStarburstLayout } from './collectionFreeForm'
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import './CollectionPileView.scss';
 import { CollectionSubView } from './CollectionSubView';
-import * as React from 'react';
 
 @observer
 export class CollectionPileView extends CollectionSubView() {
diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx
index fb8bc4da2..fa3844aa4 100644
--- a/src/client/views/collections/CollectionStackedTimeline.tsx
+++ b/src/client/views/collections/CollectionStackedTimeline.tsx
@@ -20,7 +20,7 @@ import { ScriptingGlobals } from '../../util/ScriptingGlobals';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { undoBatch, UndoManager } from '../../util/UndoManager';
-import { CollectionSubView, SubCollectionViewProps } from '../collections/CollectionSubView';
+import { CollectionSubView } from '../collections/CollectionSubView';
 import { LightboxView } from '../LightboxView';
 import { AudioWaveform } from '../nodes/audio/AudioWaveform';
 import { DocFocusFunc, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../nodes/DocumentView';
@@ -56,7 +56,7 @@ export enum TrimScope {
 @observer
 export class CollectionStackedTimeline extends CollectionSubView<CollectionStackedTimelineProps>() {
     @observable static SelectingRegion: CollectionStackedTimeline | undefined = undefined;
-    @observable public static CurrentlyPlaying: DocumentView[];
+    @observable public static CurrentlyPlaying: DocumentView[] = [];
     constructor(props: any) {
         super(props);
         makeObservable(this);
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index f9d575da2..69f1c332d 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -20,8 +20,8 @@ import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
-import './CollectionStackingView.scss';
 import { ObservableReactComponent } from '../ObservableReactComponent';
+import './CollectionStackingView.scss';
 
 // So this is how we are storing a column
 interface CSVFieldColumnProps {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 2ff435ce2..570330174 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -4,11 +4,11 @@ import * as rp from 'request-promise';
 import { Utils, returnFalse } from '../../../Utils';
 import CursorField from '../../../fields/CursorField';
 import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate, DocData } from '../../../fields/DocSymbols';
+import { AclPrivate } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { listSpec } from '../../../fields/Schema';
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { BoolCast, Cast, ScriptCast, StrCast } from '../../../fields/Types';
 import { WebField } from '../../../fields/URLField';
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
@@ -41,8 +41,8 @@ export function CollectionSubView<X>(moreProps?: X) {
             makeObservable(this);
         }
 
-        @observable _focusFilters: Opt<string[]>; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it
-        @observable _focusRangeFilters: Opt<string[]>; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it
+        @observable _focusFilters: Opt<string[]> = undefined; // childFilters that are overridden when previewing a link to an anchor which has childFilters set on it
+        @observable _focusRangeFilters: Opt<string[]> = undefined; // childFiltersByRanges that are overridden when previewing a link to an anchor which has childFiltersByRanges set on it
         protected createDashEventsTarget = (ele: HTMLDivElement | null) => {
             this.dropDisposer?.();
             this.gestureDisposer?.();
diff --git a/src/client/views/collections/CollectionTimeView.tsx b/src/client/views/collections/CollectionTimeView.tsx
index 6033b897d..7bbdb7073 100644
--- a/src/client/views/collections/CollectionTimeView.tsx
+++ b/src/client/views/collections/CollectionTimeView.tsx
@@ -1,6 +1,8 @@
 import { toUpper } from 'lodash';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { emptyFunction, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
 import { Doc, Opt, StrListCast } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
 import { ObjectField } from '../../../fields/ObjectField';
@@ -8,7 +10,6 @@ import { RichTextField } from '../../../fields/RichTextField';
 import { listSpec } from '../../../fields/Schema';
 import { ComputedField, ScriptField } from '../../../fields/ScriptField';
 import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyString, returnFalse, returnTrue, setupMoveUpEvents } from '../../../Utils';
 import { Docs } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
@@ -17,20 +18,19 @@ import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
 import { DocFocusOptions, DocumentView } from '../nodes/DocumentView';
 import { PresBox } from '../nodes/trails';
-import { computePivotLayout, computeTimelineLayout, ViewDefBounds } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
-import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionSubView } from './CollectionSubView';
 import './CollectionTimeView.scss';
-import * as React from 'react';
+import { ViewDefBounds, computePivotLayout, computeTimelineLayout } from './collectionFreeForm/CollectionFreeFormLayoutEngines';
+import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 
 @observer
 export class CollectionTimeView extends CollectionSubView() {
     _changing = false;
     @observable _layoutEngine = computePivotLayout.name;
     @observable _collapsed: boolean = false;
-    @observable _childClickedScript: Opt<ScriptField>;
-    @observable _viewDefDivClick: Opt<ScriptField>;
-    @observable _focusPivotField: Opt<string>;
+    @observable _childClickedScript: Opt<ScriptField> = undefined;
+    @observable _viewDefDivClick: Opt<ScriptField> = undefined;
+    @observable _focusPivotField: Opt<string> = undefined;
 
     constructor(props: any) {
         super(props);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0656843cb..c2f5ab2c0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -16,6 +16,7 @@ import { ContextMenuProps } from '../ContextMenuItem';
 import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
 import { OpenWhere } from '../nodes/DocumentView';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
+import { CollectionCalendarView } from './CollectionCalendarView';
 import { CollectionCarousel3DView } from './CollectionCarousel3DView';
 import { CollectionCarouselView } from './CollectionCarouselView';
 import { CollectionDockingView } from './CollectionDockingView';
@@ -28,7 +29,6 @@ import { CollectionTreeView } from './CollectionTreeView';
 import './CollectionView.scss';
 import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormView';
 import { CollectionGridView } from './collectionGrid/CollectionGridView';
-import { CollectionCalendarView } from './CollectionCalendarView';
 import { CollectionLinearView } from './collectionLinear';
 import { CollectionMulticolumnView } from './collectionMulticolumn/CollectionMulticolumnView';
 import { CollectionMultirowView } from './collectionMulticolumn/CollectionMultirowView';
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index f3071b316..4523a4f1e 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -1,6 +1,6 @@
-import * as React from "react";
-import { observable, runInAction } from "mobx";
-import { observer } from "mobx-react";
+import { observable, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
 
 interface IKeyRestrictionProps {
     contains: boolean;
@@ -19,37 +19,28 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
         if (this._key && this._value) {
             let parsedValue: string | number = `"${this._value}"`;
             const parsed = parseInt(this._value);
-            let type = "string";
+            let type = 'string';
             if (!isNaN(parsed)) {
                 parsedValue = parsed;
-                type = "number";
+                type = 'number';
             }
-            const scriptText = `${this._contains ? "" : "!"}(((doc.${this._key} && (doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))) ||
-                ((doc.data_ext && doc.data_ext.${this._key}) && (doc.data_ext.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))))`;
+            const scriptText = `${this._contains ? '' : '!'}(((doc.${this._key} && (doc.${this._key} as ${type})${type === 'string' ? '.includes' : '<='}(${parsedValue}))) ||
+                ((doc.data_ext && doc.data_ext.${this._key}) && (doc.data_ext.${this._key} as ${type})${type === 'string' ? '.includes' : '<='}(${parsedValue}))))`;
             // let doc = new Doc();
             // ((doc.data_ext && doc.data_ext!.text) && (doc.data_ext!.text as string).includes("hello"));
             this.props.script(scriptText);
-        }
-        else {
-            this.props.script("");
+        } else {
+            this.props.script('');
         }
 
         return (
             <div className="collectionViewBaseChrome-viewSpecsMenu-row">
-                <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
-                    value={this._key}
-                    onChange={(e) => runInAction(() => this._key = e.target.value)}
-                    placeholder="KEY" />
-                <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
-                    style={{ background: this._contains ? "#77dd77" : "#ff6961" }}
-                    onClick={() => runInAction(() => this._contains = !this._contains)}>
-                    {this._contains ? "CONTAINS" : "DOES NOT CONTAIN"}
+                <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft" value={this._key} onChange={e => runInAction(() => (this._key = e.target.value))} placeholder="KEY" />
+                <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle" style={{ background: this._contains ? '#77dd77' : '#ff6961' }} onClick={() => runInAction(() => (this._contains = !this._contains))}>
+                    {this._contains ? 'CONTAINS' : 'DOES NOT CONTAIN'}
                 </button>
-                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
-                    value={this._value}
-                    onChange={(e) => runInAction(() => this._value = e.target.value)}
-                    placeholder="VALUE" />
+                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight" value={this._value} onChange={e => runInAction(() => (this._value = e.target.value))} placeholder="VALUE" />
             </div>
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index a7705ea7e..72882ac17 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -93,7 +93,7 @@ export class TreeView extends ObservableReactComponent<TreeViewProps> {
     static _openLevelScript: Opt<ScriptField | undefined>;
     private _header: React.RefObject<HTMLDivElement> = React.createRef();
     private _tref = React.createRef<HTMLDivElement>();
-    @observable _docRef: Opt<DocumentView>;
+    @observable _docRef: Opt<DocumentView> = undefined;
     private _disposers: { [name: string]: IReactionDisposer } = {};
     private _editTitleScript: (() => ScriptField) | undefined;
     private _openScript: (() => ScriptField) | undefined;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
index 99ee5ef4e..08dfb32ad 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormBackgroundGrid.tsx
@@ -1,8 +1,8 @@
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
 import { NumCast } from '../../../../fields/Types';
 import './CollectionFreeFormView.scss';
-import * as React from 'react';
 
 export interface CollectionFreeFormViewBackgroundGridProps {
     panX: () => number;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
index 2606304d0..58f6b1593 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoState.tsx
@@ -1,5 +1,5 @@
 import { IconButton, Size, Type } from 'browndash-components';
-import { action, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { SettingsManager } from '../../../util/SettingsManager';
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
index 15e4d8360..8628ca3c3 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormInfoUI.tsx
@@ -1,16 +1,16 @@
-import { IReactionDisposer, makeObservable, observable, runInAction } from 'mobx';
+import { makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, DocListCast, Field, FieldResult } from '../../../../fields/Doc';
 import { InkTool } from '../../../../fields/InkField';
+import { StrCast } from '../../../../fields/Types';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { LinkManager } from '../../../util/LinkManager';
-import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
-import { CollectionFreeFormInfoState, InfoState, infoState, StateEntryFunc } from './CollectionFreeFormInfoState';
+import { DocButtonState, DocumentLinksButton } from '../../nodes/DocumentLinksButton';
+import { CollectionFreeFormInfoState, InfoState, StateEntryFunc, infoState } from './CollectionFreeFormInfoState';
 import { CollectionFreeFormView } from './CollectionFreeFormView';
 import './CollectionFreeFormView.scss';
-import { StrCast } from '../../../../fields/Types';
 
 export interface CollectionFreeFormInfoUIProps {
     Document: Doc;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
index 779a0bf96..95d521f65 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinksView.tsx
@@ -1,11 +1,11 @@
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Id } from '../../../../fields/FieldSymbols';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { LightboxView } from '../../LightboxView';
-import './CollectionFreeFormLinksView.scss';
 import { CollectionFreeFormLinkView } from './CollectionFreeFormLinkView';
-import * as React from 'react';
+import './CollectionFreeFormLinksView.scss';
 
 @observer
 export class CollectionFreeFormLinksView extends React.Component {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
index f54726a00..ec8416303 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormPannableContents.tsx
@@ -1,12 +1,11 @@
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
 import { ScriptField } from '../../../../fields/ScriptField';
 import { PresBox } from '../../nodes/trails/PresBox';
-import './CollectionFreeFormView.scss';
-import * as React from 'react';
 import { CollectionFreeFormView } from './CollectionFreeFormView';
-
+import './CollectionFreeFormView.scss';
 export interface CollectionFreeFormPannableContentsProps {
     Document: Doc;
     viewDefDivClick?: ScriptField;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
index 45e24bbb2..fa8218bdd 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormRemoteCursors.tsx
@@ -1,6 +1,8 @@
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
 import * as mobxUtils from 'mobx-utils';
+import * as React from 'react';
+import * as uuid from 'uuid';
 import CursorField from '../../../../fields/CursorField';
 import { Doc, FieldResult } from '../../../../fields/Doc';
 import { Id } from '../../../../fields/FieldSymbols';
@@ -9,8 +11,6 @@ import { listSpec } from '../../../../fields/Schema';
 import { Cast } from '../../../../fields/Types';
 import { CollectionViewProps } from '../CollectionView';
 import './CollectionFreeFormView.scss';
-import * as React from 'react';
-import * as uuid from 'uuid';
 
 @observer
 export class CollectionFreeFormRemoteCursors extends React.Component<CollectionViewProps> {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 645e9cff7..cc0833698 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -37,6 +37,7 @@ import { CtrlKey } from '../../GlobalKeyHandler';
 import { ActiveInkWidth, InkingStroke, SetActiveInkColor, SetActiveInkWidth } from '../../InkingStroke';
 import { LightboxView } from '../../LightboxView';
 import { CollectionFreeFormDocumentView, CollectionFreeFormDocumentViewWrapper } from '../../nodes/CollectionFreeFormDocumentView';
+import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
 import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from '../../nodes/DocumentView';
 import { FieldViewProps } from '../../nodes/FieldView';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
@@ -52,7 +53,6 @@ import { CollectionFreeFormPannableContents } from './CollectionFreeFormPannable
 import { CollectionFreeFormRemoteCursors } from './CollectionFreeFormRemoteCursors';
 import './CollectionFreeFormView.scss';
 import { MarqueeView } from './MarqueeView';
-import { SchemaCSVPopUp } from '../../nodes/DataVizBox/SchemaCSVPopUp';
 
 export type collectionFreeformViewProps = {
     NativeWidth?: () => number;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index b22fdfa19..39d828302 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -16,19 +16,18 @@ import { DocumentType } from '../../../documents/DocumentTypes';
 import { DocUtils, Docs, DocumentOptions } from '../../../documents/Documents';
 import { SelectionManager } from '../../../util/SelectionManager';
 import { freeformScrollMode } from '../../../util/SettingsManager';
+import { SnappingManager } from '../../../util/SnappingManager';
 import { Transform } from '../../../util/Transform';
 import { UndoManager, undoBatch } from '../../../util/UndoManager';
 import { ContextMenu } from '../../ContextMenu';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
 import { PreviewCursor } from '../../PreviewCursor';
-import { DocumentView, OpenWhere } from '../../nodes/DocumentView';
+import { OpenWhere } from '../../nodes/DocumentView';
 import { pasteImageBitmap } from '../../nodes/WebBoxRenderer';
 import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { SubCollectionViewProps } from '../CollectionSubView';
 import { MarqueeOptionsMenu } from './MarqueeOptionsMenu';
 import './MarqueeView.scss';
-import { SnappingManager } from '../../../util/SnappingManager';
-
 interface MarqueeViewProps {
     getContainerTransform: () => Transform;
     getTransform: () => Transform;
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 1e19964d7..3e75257e5 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -7,7 +7,6 @@ import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types
 import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils';
 import { Docs } from '../../../documents/Documents';
 import { DragManager } from '../../../util/DragManager';
-import { SnappingManager } from '../../../util/SnappingManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
 import { ContextMenu } from '../../ContextMenu';
@@ -17,13 +16,12 @@ import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionGridView.scss';
 import Grid, { Layout } from './Grid';
-
 @observer
 export class CollectionGridView extends CollectionSubView() {
     private _containerRef: React.RefObject<HTMLDivElement> = React.createRef();
     private _changeListenerDisposer: Opt<Lambda>; // listens for changes in this.childLayoutPairs
     private _resetListenerDisposer: Opt<Lambda>; // listens for when the reset button is clicked
-    @observable private _rowHeight: Opt<number>; // temporary store of row height to make change undoable
+    @observable private _rowHeight: Opt<number> = undefined; // temporary store of row height to make change undoable
     @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll
     private dropLocation: object = {}; // sets the drop location for external drops
 
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 3d1d87aa0..9145d7ef1 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -1,5 +1,5 @@
-import * as React from 'react';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 
 import '../../../../../node_modules/react-grid-layout/css/styles.css';
 import '../../../../../node_modules/react-resizable/css/styles.css';
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
index e12bcd8b0..5bea59e7b 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx
@@ -4,13 +4,13 @@ import { Button } from 'browndash-components';
 import { action, computed, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { returnFalse } from '../../../../Utils';
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { returnFalse } from '../../../../Utils';
 import { DragManager, dropActionType } from '../../../util/DragManager';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { Transform } from '../../../util/Transform';
-import { undoable, undoBatch } from '../../../util/UndoManager';
+import { undoBatch, undoable } from '../../../util/UndoManager';
 import { DocumentView } from '../../nodes/DocumentView';
 import { CollectionSubView } from '../CollectionSubView';
 import './CollectionMulticolumnView.scss';
diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
index 7dbc18e60..3043eb0f8 100644
--- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
+++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx
@@ -1,9 +1,9 @@
 import { action, computed, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { returnFalse } from '../../../../Utils';
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
-import { returnFalse } from '../../../../Utils';
 import { DragManager, dropActionType } from '../../../util/DragManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
@@ -12,7 +12,6 @@ import { CollectionSubView } from '../CollectionSubView';
 import './CollectionMultirowView.scss';
 import HeightLabel from './MultirowHeightLabel';
 import ResizeBar from './MultirowResizer';
-
 interface HeightSpecifier {
     magnitude: number;
     unit: string;
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
index 868b1140d..ea99bff2e 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnResizer.tsx
@@ -1,12 +1,12 @@
-import * as React from 'react';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { observable, action } from 'mobx';
+import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
 import { NumCast, StrCast } from '../../../../fields/Types';
-import { DimUnit } from './CollectionMulticolumnView';
 import { UndoManager } from '../../../util/UndoManager';
-import { StyleProviderFunc } from '../../nodes/DocumentView';
 import { StyleProp } from '../../StyleProvider';
+import { StyleProviderFunc } from '../../nodes/DocumentView';
+import { DimUnit } from './CollectionMulticolumnView';
 
 interface ResizerProps {
     width: number;
diff --git a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
index 9985a9fba..a9579d931 100644
--- a/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MulticolumnWidthLabel.tsx
@@ -1,27 +1,25 @@
-import * as React from "react";
-import { observer } from "mobx-react";
-import { computed } from "mobx";
-import { Doc } from "../../../../fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
-import { EditableView } from "../../EditableView";
-import { DimUnit } from "./CollectionMulticolumnView";
+import { computed } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc } from '../../../../fields/Doc';
+import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
+import { EditableView } from '../../EditableView';
+import { DimUnit } from './CollectionMulticolumnView';
 
 interface WidthLabelProps {
     layout: Doc;
     collectionDoc: Doc;
-    decimals?: number;
 }
 
 @observer
 export default class WidthLabel extends React.Component<WidthLabelProps> {
-
     @computed
     private get contents() {
-        const { layout, decimals } = this.props;
+        const { layout } = this.props;
         const getUnit = () => StrCast(layout.dimUnit);
-        const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3));
+        const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(3));
         return (
-            <div className={"label-wrapper"}>
+            <div className={'label-wrapper'}>
                 <EditableView
                     GetValue={getMagnitude}
                     SetValue={value => {
@@ -50,7 +48,6 @@ export default class WidthLabel extends React.Component<WidthLabelProps> {
     }
 
     render() {
-        return BoolCast(this.props.collectionDoc.showWidthLabels) ? this.contents : (null);
+        return BoolCast(this.props.collectionDoc.showWidthLabels) ? this.contents : null;
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
index aa5439fa4..878c7ff3c 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowHeightLabel.tsx
@@ -1,10 +1,10 @@
-import * as React from "react";
-import { observer } from "mobx-react";
-import { computed } from "mobx";
-import { Doc } from "../../../../fields/Doc";
-import { NumCast, StrCast, BoolCast } from "../../../../fields/Types";
-import { EditableView } from "../../EditableView";
-import { DimUnit } from "./CollectionMultirowView";
+import { computed } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc } from '../../../../fields/Doc';
+import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
+import { EditableView } from '../../EditableView';
+import { DimUnit } from './CollectionMultirowView';
 
 interface HeightLabelProps {
     layout: Doc;
@@ -14,14 +14,13 @@ interface HeightLabelProps {
 
 @observer
 export default class HeightLabel extends React.Component<HeightLabelProps> {
-
     @computed
     private get contents() {
         const { layout, decimals } = this.props;
         const getUnit = () => StrCast(layout.dimUnit);
         const getMagnitude = () => String(+NumCast(layout.dimMagnitude).toFixed(decimals ?? 3));
         return (
-            <div className={"label-wrapper"}>
+            <div className={'label-wrapper'}>
                 <EditableView
                     GetValue={getMagnitude}
                     SetValue={value => {
@@ -50,7 +49,6 @@ export default class HeightLabel extends React.Component<HeightLabelProps> {
     }
 
     render() {
-        return BoolCast(this.props.collectionDoc.showHeightLabels) ? this.contents : (null);
+        return BoolCast(this.props.collectionDoc.showHeightLabels) ? this.contents : null;
     }
-
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
index 5a9d6a82c..7dee65e58 100644
--- a/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
+++ b/src/client/views/collections/collectionMulticolumn/MultirowResizer.tsx
@@ -1,12 +1,12 @@
-import * as React from 'react';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { observable, action } from 'mobx';
+import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
 import { NumCast, StrCast } from '../../../../fields/Types';
-import { DimUnit } from './CollectionMultirowView';
 import { UndoManager } from '../../../util/UndoManager';
 import { StyleProp } from '../../StyleProvider';
 import { StyleProviderFunc } from '../../nodes/DocumentView';
+import { DimUnit } from './CollectionMultirowView';
 
 interface ResizerProps {
     height: number;
diff --git a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
index 04443b4a7..5f8b412be 100644
--- a/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
+++ b/src/client/views/collections/collectionSchema/SchemaColumnHeader.tsx
@@ -1,7 +1,7 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from 'mobx';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
 import { Colors } from '../../global/globalEnums';
 import './CollectionSchemaView.scss';
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 06073b52c..85e97f95f 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -1,3 +1,4 @@
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, makeObservable, observable } from 'mobx';
@@ -7,18 +8,17 @@ import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../Utils';
 import { Doc } from '../../../fields/Doc';
 import { Cast, DocCast, StrCast } from '../../../fields/Types';
 import { WebField } from '../../../fields/URLField';
+import { DocumentType } from '../../documents/DocumentTypes';
 import { DragManager } from '../../util/DragManager';
 import { LinkFollower } from '../../util/LinkFollower';
 import { LinkManager } from '../../util/LinkManager';
 import { SelectionManager } from '../../util/SelectionManager';
 import { SettingsManager } from '../../util/SettingsManager';
+import { undoBatch } from '../../util/UndoManager';
 import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DocumentView, DocumentViewInternal, OpenWhere } from '../nodes/DocumentView';
 import { LinkInfo } from '../nodes/LinkDocPreview';
 import './LinkMenuItem.scss';
-import { undoBatch } from '../../util/UndoManager';
-import { IconProp } from '@fortawesome/fontawesome-svg-core';
-import { DocumentType } from '../../documents/DocumentTypes';
 
 interface LinkMenuItemProps {
     groupType: string;
diff --git a/src/client/views/linking/LinkPopup.tsx b/src/client/views/linking/LinkPopup.tsx
index 5460a6daf..7e344dd7a 100644
--- a/src/client/views/linking/LinkPopup.tsx
+++ b/src/client/views/linking/LinkPopup.tsx
@@ -1,16 +1,16 @@
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import { EditorView } from 'prosemirror-view';
-import { Doc } from '../../../fields/Doc';
+import * as React from 'react';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
+import { Doc } from '../../../fields/Doc';
 import { Transform } from '../../util/Transform';
 import { undoBatch } from '../../util/UndoManager';
+import { DefaultStyleProvider } from '../StyleProvider';
 import { OpenWhere } from '../nodes/DocumentView';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { SearchBox } from '../search/SearchBox';
-import { DefaultStyleProvider } from '../StyleProvider';
 import './LinkPopup.scss';
-import * as React from 'react';
 
 interface LinkPopupProps {
     linkFrom?: () => Doc | undefined;
@@ -29,7 +29,7 @@ interface LinkPopupProps {
 @observer
 export class LinkPopup extends React.Component<LinkPopupProps> {
     @observable private linkURL: string = '';
-    @observable public view?: EditorView;
+    @observable public view?: EditorView = undefined;
 
     // TODO: should check for valid URL
     @undoBatch
diff --git a/src/client/views/linking/LinkRelationshipSearch.tsx b/src/client/views/linking/LinkRelationshipSearch.tsx
index 3e7f5be74..0902d53b2 100644
--- a/src/client/views/linking/LinkRelationshipSearch.tsx
+++ b/src/client/views/linking/LinkRelationshipSearch.tsx
@@ -1,6 +1,6 @@
 import { observer } from 'mobx-react';
-import './LinkEditor.scss';
 import * as React from 'react';
+import './LinkEditor.scss';
 
 interface link_relationshipSearchProps {
     results: string[] | undefined;
diff --git a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
index 72b63cf8f..bce2b296f 100644
--- a/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
+++ b/src/client/views/newlightbox/ButtonMenu/ButtonMenu.tsx
@@ -3,12 +3,12 @@ import * as React from 'react';
 import { Doc } from '../../../../fields/Doc';
 import { InkTool } from '../../../../fields/InkField';
 import { SelectionManager } from '../../../util/SelectionManager';
+import { SnappingManager } from '../../../util/SnappingManager';
 import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { DocumentView, OpenWhereMod } from '../../nodes/DocumentView';
+import { OpenWhereMod } from '../../nodes/DocumentView';
 import { NewLightboxView } from '../NewLightboxView';
 import './ButtonMenu.scss';
 import { IButtonMenu } from './utils';
-import { SnappingManager } from '../../../util/SnappingManager';
 
 export const ButtonMenu = (props: IButtonMenu) => {
     return (
diff --git a/src/client/views/newlightbox/NewLightboxView.tsx b/src/client/views/newlightbox/NewLightboxView.tsx
index 6980e31c1..3d159c3e3 100644
--- a/src/client/views/newlightbox/NewLightboxView.tsx
+++ b/src/client/views/newlightbox/NewLightboxView.tsx
@@ -2,28 +2,28 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnTrue } from '../../../Utils';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
 import { InkTool } from '../../../fields/InkField';
 import { Cast, NumCast, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../../../Utils';
 import { DocUtils } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
 import { LinkManager } from '../../util/LinkManager';
 import { SelectionManager } from '../../util/SelectionManager';
+import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
-import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
-import { TabDocView } from '../collections/TabDocView';
 import { GestureOverlay } from '../GestureOverlay';
 import { LightboxView } from '../LightboxView';
-import { DocumentView, OpenWhere } from '../nodes/DocumentView';
 import { DefaultStyleProvider } from '../StyleProvider';
-import { IRecommendation } from './components';
+import { CollectionStackedTimeline } from '../collections/CollectionStackedTimeline';
+import { TabDocView } from '../collections/TabDocView';
+import { DocumentView, OpenWhere } from '../nodes/DocumentView';
 import { ExploreView } from './ExploreView';
-import { emptyBounds, IBounds } from './ExploreView/utils';
+import { IBounds, emptyBounds } from './ExploreView/utils';
 import { NewLightboxHeader } from './Header';
 import './NewLightboxView.scss';
 import { RecommendationList } from './RecommendationList';
-import { SnappingManager } from '../../util/SnappingManager';
+import { IRecommendation } from './components';
 
 enum LightboxStatus {
     RECOMMENDATIONS = 'recommendations',
@@ -50,15 +50,15 @@ export class NewLightboxView extends React.Component<LightboxViewProps> {
         return this._doc;
     }
     private static LightboxDocTemplate = () => NewLightboxView._layoutTemplate;
-    @observable private static _layoutTemplate: Opt<Doc>;
-    @observable private static _layoutTemplateString: Opt<string>;
-    @observable private static _doc: Opt<Doc>;
-    @observable private static _docTarget: Opt<Doc>;
+    @observable private static _layoutTemplate: Opt<Doc> = undefined;
+    @observable private static _layoutTemplateString: Opt<string> = undefined;
+    @observable private static _doc: Opt<Doc> = undefined;
+    @observable private static _docTarget: Opt<Doc> = undefined;
     @observable private static _docFilters: string[] = []; // filters
-    private static _savedState: Opt<LightboxSavedState>;
+    private static _savedState: Opt<LightboxSavedState> = undefined;
     private static _history: Opt<{ doc: Doc; target?: Doc }[]> = [];
     @observable private static _future: Opt<Doc[]> = [];
-    @observable private static _docView: Opt<DocumentView>;
+    @observable private static _docView: Opt<DocumentView> = undefined;
 
     // keywords
     @observable private static _keywords: string[] = [];
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 4c36d2fcb..12e8e1a69 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -44,8 +44,8 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
     anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
     crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined;
-    @observable schemaDataVizChildren: any;
-    @observable _marqueeing: number[] | undefined;
+    @observable schemaDataVizChildren: any = undefined;
+    @observable _marqueeing: number[] | undefined = undefined;
     @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
     @computed get annotationLayer() {
         TraceMobx();
diff --git a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
index 3cb5125da..24023077f 100644
--- a/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
+++ b/src/client/views/nodes/DataVizBox/SchemaCSVPopUp.tsx
@@ -1,15 +1,14 @@
-import * as React from 'react';
-import './SchemaCSVPopUp.scss';
+import { IconButton } from 'browndash-components';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { CgClose } from 'react-icons/cg';
+import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils';
 import { Doc } from '../../../../fields/Doc';
-import { Button, IconButton, Type } from 'browndash-components';
 import { StrCast } from '../../../../fields/Types';
-import { MarqueeView } from '../../collections/collectionFreeForm/MarqueeView';
-import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils';
 import { DragManager } from '../../../util/DragManager';
 import { DocumentView } from '../DocumentView';
-import { CgClose } from 'react-icons/cg';
+import './SchemaCSVPopUp.scss';
 
 interface SchemaCSVPopUpProps {}
 
@@ -56,13 +55,11 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
             <div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
                 {this.heading('Schema Table as Data Visualization Doc')}
                 <div className="image-content-wrapper">
-                        <div className="img-wrapper">
-                            <div className="img-container" onPointerDown={e => this.drag(e)}>
-                                <img
-                                    width={150} height={150} src={"/assets/dataVizBox.png"}
-                                />
-                            </div>
+                    <div className="img-wrapper">
+                        <div className="img-container" onPointerDown={e => this.drag(e)}>
+                            <img width={150} height={150} src={'/assets/dataVizBox.png'} />
                         </div>
+                    </div>
                 </div>
             </div>
         );
@@ -88,9 +85,10 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
                     return embedding;
                 };
                 if (this.view && sourceAnchorCreator && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
-                    DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], 
-                        new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
-                        dragComplete: e => {this.setVisible(false);},
+                    DragManager.StartAnchorAnnoDrag(e.target instanceof HTMLElement ? [e.target] : [], new DragManager.AnchorAnnoDragData(this.view, sourceAnchorCreator, targetCreator), downX, downY, {
+                        dragComplete: e => {
+                            this.setVisible(false);
+                        },
                     });
                     return true;
                 }
@@ -108,4 +106,4 @@ export class SchemaCSVPopUp extends React.Component<SchemaCSVPopUpProps> {
             </div>
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/nodes/DataVizBox/components/Histogram.tsx b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
index 227c993c7..9e9a43b34 100644
--- a/src/client/views/nodes/DataVizBox/components/Histogram.tsx
+++ b/src/client/views/nodes/DataVizBox/components/Histogram.tsx
@@ -1,7 +1,7 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { ColorPicker, EditableText, IconButton, Size, Type } from 'browndash-components';
 import * as d3 from 'd3';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaFillDrip } from 'react-icons/fa';
@@ -11,10 +11,10 @@ import { listSpec } from '../../../../../fields/Schema';
 import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
 import { Docs } from '../../../../documents/Documents';
 import { undoable } from '../../../../util/UndoManager';
+import { ObservableReactComponent } from '../../../ObservableReactComponent';
 import { PinProps, PresBox } from '../../trails';
 import { scaleCreatorNumerical, yAxisCreator } from '../utils/D3Utils';
 import './Chart.scss';
-import { ObservableReactComponent } from '../../../ObservableReactComponent';
 
 export interface HistogramProps {
     Document: Doc;
@@ -461,7 +461,7 @@ export class Histogram extends ObservableReactComponent<HistogramProps> {
 
         if (this._histogramData.length > 0 || !this.parentViz) {
             return this._props.axes.length >= 1 ? (
-                <div className="chart-container" style={{width: this._props.width+this._props.margin.right}}>
+                <div className="chart-container" style={{ width: this._props.width + this._props.margin.right }}>
                     <div className="graph-title">
                         <EditableText
                             val={StrCast(this._props.layoutDoc[titleAccessor])}
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 4b0df0457..a69f083d1 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -1,6 +1,6 @@
 import { Button, EditableText, Size } from 'browndash-components';
 import * as d3 from 'd3';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, DocListCast, NumListCast, StrListCast } from '../../../../../fields/Doc';
@@ -10,11 +10,11 @@ import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
 import { Docs } from '../../../../documents/Documents';
 import { DocumentManager } from '../../../../util/DocumentManager';
 import { undoable } from '../../../../util/UndoManager';
+import { ObservableReactComponent } from '../../../ObservableReactComponent';
 import { PinProps, PresBox } from '../../trails';
 import { DataVizBox } from '../DataVizBox';
 import { createLineGenerator, drawLine, minMaxRange, scaleCreatorNumerical, xAxisCreator, xGrid, yAxisCreator, yGrid } from '../utils/D3Utils';
 import './Chart.scss';
-import { ObservableReactComponent } from '../../../ObservableReactComponent';
 
 export interface DataPoint {
     x: number;
@@ -48,12 +48,11 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
     private _lineChartSvg: d3.Selection<SVGGElement, unknown, null, undefined> | undefined;
     @observable _currSelected: SelectedDataPoint | undefined = undefined;
     // TODO: nda - some sort of mapping that keeps track of the annotated points so we can easily remove when annotations list updates
-    constructor(props:any) {
+    constructor(props: any) {
         super(props);
         makeObservable(this);
     }
 
-
     @computed get _tableDataIds() {
         return !this.parentViz ? this._props.records.map((rec, i) => i) : NumListCast(this.parentViz.dataViz_selectedRows);
     }
@@ -359,7 +358,7 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
         const selectedPt = this._currSelected ? `{ ${this._props.axes[0]}: ${this._currSelected.x} ${this._props.axes[1]}: ${this._currSelected.y} }` : 'none';
         if (this._lineChartData.length > 0 || !this.parentViz || this.parentViz.length == 0) {
             return this._props.axes.length >= 2 && /\d/.test(this._props.records[0][this._props.axes[0]]) && /\d/.test(this._props.records[0][this._props.axes[1]]) ? (
-                <div className="chart-container" style={{width: this.props.width+this.props.margin.right}}>
+                <div className="chart-container" style={{ width: this.props.width + this.props.margin.right }}>
                     <div className="graph-title">
                         <EditableText
                             val={StrCast(this._props.layoutDoc[titleAccessor])}
@@ -373,16 +372,17 @@ export class LineChart extends ObservableReactComponent<LineChartProps> {
                         />
                     </div>
                     <div ref={this._lineChartRef} />
-                    {selectedPt != 'none' ? 
-                        <div className={'selected-data'}> 
+                    {selectedPt != 'none' ? (
+                        <div className={'selected-data'}>
                             {`Selected: ${selectedPt}`}
-                            <Button onClick={e=>{
-                                console.log("test plzz")
-                                this.props.vizBox.sidebarBtnDown;
-                                this.props.vizBox.sidebarAddDocument;}
-                                }></Button>
-                        </div> 
-                        : null}
+                            <Button
+                                onClick={e => {
+                                    console.log('test plzz');
+                                    this.props.vizBox.sidebarBtnDown;
+                                    this.props.vizBox.sidebarAddDocument;
+                                }}></Button>
+                        </div>
+                    ) : null}
                 </div>
             ) : (
                 <span className="chart-container"> {'first use table view to select two numerical axes to plot'}</span>
diff --git a/src/client/views/nodes/DataVizBox/components/PieChart.tsx b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
index e644870da..e67556cd0 100644
--- a/src/client/views/nodes/DataVizBox/components/PieChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/PieChart.tsx
@@ -1,7 +1,7 @@
 import { Checkbox } from '@mui/material';
 import { ColorPicker, EditableText, Size, Type } from 'browndash-components';
 import * as d3 from 'd3';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { FaFillDrip } from 'react-icons/fa';
@@ -11,9 +11,9 @@ import { listSpec } from '../../../../../fields/Schema';
 import { Cast, DocCast, StrCast } from '../../../../../fields/Types';
 import { Docs } from '../../../../documents/Documents';
 import { undoable } from '../../../../util/UndoManager';
+import { ObservableReactComponent } from '../../../ObservableReactComponent';
 import { PinProps, PresBox } from '../../trails';
 import './Chart.scss';
-import { ObservableReactComponent } from '../../../ObservableReactComponent';
 
 export interface PieChartProps {
     Document: Doc;
@@ -356,7 +356,7 @@ export class PieChart extends ObservableReactComponent<PieChartProps> {
 
         if (this._pieChartData.length > 0 || !this.parentViz) {
             return this._props.axes.length >= 1 ? (
-                <div className="chart-container" style={{width: this._props.width+this._props.margin.right}}>
+                <div className="chart-container" style={{ width: this._props.width + this._props.margin.right }}>
                     <div className="graph-title">
                         <EditableText
                             val={StrCast(this._props.layoutDoc[titleAccessor])}
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index 4f60a156b..f127fecf3 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -1,17 +1,17 @@
 import { Button, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, makeObservable, observable, reaction, trace } from 'mobx';
+import { IReactionDisposer, action, computed, makeObservable, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../../Utils';
 import { Doc, Field, NumListCast } from '../../../../../fields/Doc';
 import { List } from '../../../../../fields/List';
 import { listSpec } from '../../../../../fields/Schema';
 import { Cast, DocCast } from '../../../../../fields/Types';
-import { emptyFunction, setupMoveUpEvents, Utils } from '../../../../../Utils';
 import { DragManager } from '../../../../util/DragManager';
+import { ObservableReactComponent } from '../../../ObservableReactComponent';
 import { DocumentView } from '../../DocumentView';
 import { DataVizView } from '../DataVizBox';
 import './Chart.scss';
-import { ObservableReactComponent } from '../../../ObservableReactComponent';
 const {  default: { DATA_VIZ_TABLE_ROW_HEIGHT } } = require('../../../global/globalCssVariables.module.scss'); // prettier-ignore
 interface TableBoxProps {
     Document: Doc;
@@ -87,7 +87,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
         return (this.viewScale * this._tableHeight) / this._tableDataIds.length;
     }
     @computed get startID() {
-        return this.rowHeight ? Math.max(Math.floor(this._scrollTop / this.rowHeight)-1, 0) : 0;
+        return this.rowHeight ? Math.max(Math.floor(this._scrollTop / this.rowHeight) - 1, 0) : 0;
     }
     @computed get endID() {
         console.log('start = ' + this.startID + '  container = ' + this._tableContainerHeight + ' scale = ' + this.viewScale + ' row = ' + this.rowHeight);
@@ -169,7 +169,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
             return (
                 <div
                     className="tableBox"
-                    style={{width: this.props.width+this.props.margin.right}}
+                    style={{ width: this.props.width + this.props.margin.right }}
                     tabIndex={0}
                     onKeyDown={e => {
                         if (this._props.layoutDoc && e.key === 'a' && (e.ctrlKey || e.metaKey)) {
@@ -226,7 +226,7 @@ export class TableBox extends ObservableReactComponent<TableBoxProps> {
                             </thead>
                             <tbody>
                                 {this._tableDataIds
-                                    .filter((rowId, i) => this.startID-2 <= i && i <= this.endID+2)
+                                    .filter((rowId, i) => this.startID - 2 <= i && i <= this.endID + 2)
                                     ?.map(rowId => (
                                         <tr
                                             key={rowId}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index fa472312e..4cc7fe4c8 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,6 +1,7 @@
-import { computed, makeObservable, observable } from 'mobx';
+import { computed, makeObservable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import JsxParser from 'react-jsx-parser';
 import * as XRegExp from 'xregexp';
 import { OmitKeys, Without, emptyPath } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
@@ -10,11 +11,11 @@ import { Cast, StrCast } from '../../../fields/Types';
 import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { InkingStroke } from '../InkingStroke';
 import { ObservableReactComponent } from '../ObservableReactComponent';
+import { CollectionCalendarView } from '../collections/CollectionCalendarView';
 import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { CollectionView } from '../collections/CollectionView';
 import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
 import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
-import { CollectionCalendarView } from '../collections/CollectionCalendarView';
 import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox';
 import { PresElementBox } from '../nodes/trails/PresElementBox';
 import { SearchBox } from '../search/SearchBox';
@@ -47,7 +48,6 @@ import { WebBox } from './WebBox';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { ImportElementBox } from './importBox/ImportElementBox';
 import { PresBox } from './trails/PresBox';
-import JsxParser from 'react-jsx-parser';
 
 type BindingProps = Without<FieldViewProps, 'fieldKey'>;
 export interface JsxBindings {
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index cc7fca8d2..f8f4b94a2 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,10 +1,11 @@
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { Dropdown, DropdownType, Type } from 'browndash-components';
+import { Howl } from 'howler';
 import { IReactionDisposer, action, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { computedFn } from 'mobx-utils';
-import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
 import * as React from 'react';
+import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
 import { Utils, emptyFunction, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick } from '../../../Utils';
 import { Doc, DocListCast, Field, Opt, StrListCast } from '../../../fields/Doc';
 import { AclPrivate, Animation, AudioPlay, DocViews } from '../../../fields/DocSymbols';
@@ -53,7 +54,6 @@ import { LinkAnchorBox } from './LinkAnchorBox';
 import { FormattedTextBox } from './formattedText/FormattedTextBox';
 import { PresEffect, PresEffectDirection } from './trails';
 import { PinProps, PresBox } from './trails/PresBox';
-import { Howl } from 'howler';
 
 interface Window {
     MediaRecorder: MediaRecorder;
@@ -138,7 +138,6 @@ export interface DocComponentView {
     dragStarting?: (snapToDraggedDoc: boolean, showGroupDragTarget: boolean, visited: Set<Doc>) => void;
     incrementalRendering?: () => void;
     infoUI?: () => JSX.Element | null;
-    getCenter?: (xf: Transform) => { X: number; Y: number };
     screenBounds?: () => Opt<{ left: number; top: number; right: number; bottom: number; center?: { X: number; Y: number } }>;
     ptToScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
     ptFromScreen?: (pt: { X: number; Y: number }) => { X: number; Y: number };
@@ -1516,7 +1515,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
             const docuBox = this.docView.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
             if (docuBox.length) return { ...docuBox[0].getBoundingClientRect(), center: undefined };
         }
-        return { left, top, right, bottom, center: this.ComponentView?.getCenter?.(xf) };
+        return { left, top, right, bottom };
     };
 
     public iconify(finished?: () => void, animateTime?: number) {
diff --git a/src/client/views/nodes/FaceRectangle.tsx b/src/client/views/nodes/FaceRectangle.tsx
index 8d03bf57a..46bc6eb03 100644
--- a/src/client/views/nodes/FaceRectangle.tsx
+++ b/src/client/views/nodes/FaceRectangle.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
 import { observable, runInAction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
 import { RectangleTemplate } from './FaceRectangles';
 
 @observer
diff --git a/src/client/views/nodes/FaceRectangles.tsx b/src/client/views/nodes/FaceRectangles.tsx
index 26e720c0d..ade4225d9 100644
--- a/src/client/views/nodes/FaceRectangles.tsx
+++ b/src/client/views/nodes/FaceRectangles.tsx
@@ -1,8 +1,8 @@
+import { observer } from 'mobx-react';
 import * as React from 'react';
 import { Doc, DocListCast } from '../../../fields/Doc';
-import { Cast, NumCast } from '../../../fields/Types';
-import { observer } from 'mobx-react';
 import { Id } from '../../../fields/FieldSymbols';
+import { Cast, NumCast } from '../../../fields/Types';
 import FaceRectangle from './FaceRectangle';
 
 interface FaceRectanglesProps {
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index f4c5167a5..008f10f26 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { DateField } from '../../../fields/DateField';
 import { Doc, Field, FieldResult, Opt } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index fd8d8ef56..7bc9d3f85 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -1,7 +1,6 @@
 import { Tooltip } from '@mui/material';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
-import { ObservableGroupMap } from 'mobx-utils';
 import * as React from 'react';
 import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnZero } from '../../../Utils';
 import { Doc, Field } from '../../../fields/Doc';
@@ -11,13 +10,13 @@ import { Transform } from '../../util/Transform';
 import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { EditableView } from '../EditableView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DefaultStyleProvider } from '../StyleProvider';
 import { OpenWhere } from './DocumentView';
 import { FieldViewProps } from './FieldView';
 import { KeyValueBox } from './KeyValueBox';
 import './KeyValueBox.scss';
 import './KeyValuePair.scss';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 // Represents one row in a key value plane
 
@@ -35,12 +34,11 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
     @observable private isPointerOver = false;
     @observable public isChecked = false;
     private checkbox = React.createRef<HTMLInputElement>();
-    constructor(props:any) {
+    constructor(props: any) {
         super(props);
         makeObservable(this);
     }
 
-
     @action
     handleCheck = (e: React.ChangeEvent<HTMLInputElement>) => {
         this.isChecked = e.currentTarget.checked;
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 32300d60a..8ad0b7dde 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../../fields/Doc';
 import { LinkManager } from '../../util/LinkManager';
 import './LinkDescriptionPopup.scss';
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index d0a9f10b4..ea23ecbea 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -2,13 +2,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import wiki from 'wikijs';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
 import { Doc, Opt } from '../../../fields/Doc';
 import { Cast, DocCast, NumCast, PromiseValue, StrCast } from '../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnNone, setupMoveUpEvents } from '../../../Utils';
 import { DocServer } from '../../DocServer';
-import { Docs } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
+import { Docs } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
 import { DragManager } from '../../util/DragManager';
 import { LinkFollower } from '../../util/LinkFollower';
@@ -16,10 +17,9 @@ import { LinkManager } from '../../util/LinkManager';
 import { SearchUtil } from '../../util/SearchUtil';
 import { SettingsManager } from '../../util/SettingsManager';
 import { Transform } from '../../util/Transform';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
 import './LinkDocPreview.scss';
-import * as React from 'react';
-import { ObservableReactComponent } from '../ObservableReactComponent';
 
 export class LinkInfo {
     private static _instance: Opt<LinkInfo>;
diff --git a/src/client/views/nodes/LoadingBox.tsx b/src/client/views/nodes/LoadingBox.tsx
index 27d73a585..adccc9db6 100644
--- a/src/client/views/nodes/LoadingBox.tsx
+++ b/src/client/views/nodes/LoadingBox.tsx
@@ -1,4 +1,4 @@
-import { action, observable, runInAction } from 'mobx';
+import { observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import ReactLoading from 'react-loading';
diff --git a/src/client/views/nodes/MapBox/AnimationUtility.ts b/src/client/views/nodes/MapBox/AnimationUtility.ts
index 42dfa59b7..35153f439 100644
--- a/src/client/views/nodes/MapBox/AnimationUtility.ts
+++ b/src/client/views/nodes/MapBox/AnimationUtility.ts
@@ -1,13 +1,10 @@
-import mapboxgl from 'mapbox-gl';
-import { MercatorCoordinate } from 'mapbox-gl';
-import { MapRef } from 'react-map-gl';
-import * as React from 'react';
-import * as d3 from 'd3';
 import * as turf from '@turf/turf';
 import { Position } from '@turf/turf';
-import { Feature, FeatureCollection, GeoJsonProperties, Geometry } from 'geojson';
-import { observer } from 'mobx-react';
-import { action, computed, observable, runInAction, makeObservable } from 'mobx';
+import * as d3 from 'd3';
+import { Feature, GeoJsonProperties, Geometry } from 'geojson';
+import mapboxgl, { MercatorCoordinate } from 'mapbox-gl';
+import { action, computed, makeObservable, observable, runInAction } from 'mobx';
+import { MapRef } from 'react-map-gl';
 
 export enum AnimationStatus {
     START = 'start',
diff --git a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
index f9607becf..7e99795b5 100644
--- a/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/DirectionsAnchorMenu.tsx
@@ -1,15 +1,15 @@
-import * as React from 'react';
-import { observer } from 'mobx-react';
-import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { IconLookup, faAdd, faCalendarDays, faRoute } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconButton } from 'browndash-components';
 import { IReactionDisposer, ObservableMap, reaction } from 'mobx';
-import { Doc, Opt } from '../../../../fields/Doc';
+import { observer } from 'mobx-react';
+import * as React from 'react';
 import { returnFalse, unimplementedFunction } from '../../../../Utils';
+import { Doc, Opt } from '../../../../fields/Doc';
 import { NumCast, StrCast } from '../../../../fields/Types';
 import { SelectionManager } from '../../../util/SelectionManager';
-import { IconButton } from 'browndash-components';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { SettingsManager } from '../../../util/SettingsManager';
-import { IconLookup, faAdd, faCalendarDays, faRoute } from '@fortawesome/free-solid-svg-icons';
+import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
 
 @observer
 export class DirectionsAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
diff --git a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
index 1b1b74e7c..08bea5d9d 100644
--- a/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
+++ b/src/client/views/nodes/MapBox/MapAnchorMenu.tsx
@@ -1,26 +1,23 @@
+import { IconLookup, faAdd, faArrowDown, faArrowLeft, faArrowsRotate, faBicycle, faCalendarDays, faCar, faDiamondTurnRight, faEdit, faPersonWalking, faRoute } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import * as React from 'react';
+import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
+import { IconButton } from 'browndash-components';
+import { Position } from 'geojson';
 import { IReactionDisposer, ObservableMap, action, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
-import { Doc, NumListCast, Opt } from '../../../../fields/Doc';
+import * as React from 'react';
+import { CirclePicker, ColorResult } from 'react-color';
 import { returnFalse, setupMoveUpEvents, unimplementedFunction } from '../../../../Utils';
+import { Doc, Opt } from '../../../../fields/Doc';
+import { NumCast, StrCast } from '../../../../fields/Types';
+import { CalendarManager } from '../../../util/CalendarManager';
 import { SelectionManager } from '../../../util/SelectionManager';
-import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
-// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup';
-import { Button, IconButton } from 'browndash-components';
 import { SettingsManager } from '../../../util/SettingsManager';
+import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
 import './MapAnchorMenu.scss';
-import { NumCast, StrCast } from '../../../../fields/Types';
-import { IconLookup, faDiamondTurnRight, faCalendarDays, faEdit, faAdd, faRoute, faArrowLeft, faLocationDot, faArrowDown, faCar, faBicycle, faPersonWalking, faUpload, faArrowsRotate } from '@fortawesome/free-solid-svg-icons';
-import { DirectionsAnchorMenu } from './DirectionsAnchorMenu';
-import { Autocomplete, Checkbox, FormControlLabel, TextField } from '@mui/material';
 import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
-import { MapBox } from './MapBox';
-import { List } from '../../../../fields/List';
 import { MarkerIcons } from './MarkerIcons';
-import { CirclePicker, ColorResult } from 'react-color';
-import { Position } from 'geojson';
-import { CalendarManager } from '../../../util/CalendarManager';
+// import { GPTPopup, GPTPopupMode } from './../../GPTPopup/GPTPopup';
 
 type MapAnchorMenuType = 'standard' | 'routeCreation' | 'calendar' | 'customize' | 'route';
 
@@ -52,7 +49,6 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     public UpdateMarkerColor: (color: string) => void = unimplementedFunction;
     public UpdateMarkerIcon: (iconKey: string) => void = unimplementedFunction;
 
-
     public Hide: () => void = unimplementedFunction;
 
     public OpenAnimationPanel: (routeDoc: Doc | undefined) => void = unimplementedFunction;
@@ -74,22 +70,21 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
     private title: string | undefined = undefined;
 
     public setPinDoc(pinDoc: Doc | undefined) {
-        if (pinDoc){
+        if (pinDoc) {
             this.pinDoc = pinDoc;
             this.title = StrCast(pinDoc.title ? pinDoc.title : `${NumCast(pinDoc.longitude)}, ${NumCast(pinDoc.latitude)}`);
         }
-        
     }
 
     public setRouteDoc(routeDoc: Doc | undefined) {
-        if (routeDoc){
+        if (routeDoc) {
             this.routeDoc = routeDoc;
             this.title = StrCast(routeDoc.title ?? 'Map route');
         }
     }
 
     @action
-    public Reset(){
+    public Reset() {
         this.destinationSelected = false;
         this.currentRouteInfoMap = undefined;
         this.destinationFeatures = [];
@@ -296,34 +291,23 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
         return undefined;
     };
 
-    getDirectionsButton: JSX.Element = (
-        <IconButton 
-            tooltip="Get directions" 
-            onPointerDown={this.DirectionsClick}
-            icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup} />} 
-            color={SettingsManager.userColor} />
-    )
+    getDirectionsButton: JSX.Element = (<IconButton tooltip="Get directions" onPointerDown={this.DirectionsClick} icon={<FontAwesomeIcon icon={faDiamondTurnRight as IconLookup} />} color={SettingsManager.userColor} />);
 
     getAddToCalendarButton = (docType: string): JSX.Element => {
         return (
-            <IconButton 
-            tooltip="Add to calendar" 
-            onPointerDown={() => {
-                CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc)
-            }} 
-            icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} 
-            color={SettingsManager.userColor} 
+            <IconButton
+                tooltip="Add to calendar"
+                onPointerDown={() => {
+                    CalendarManager.Instance.open(undefined, docType === 'pin' ? this.pinDoc : this.routeDoc);
+                }}
+                icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />}
+                color={SettingsManager.userColor}
             />
-        )
-       
-    }
+        );
+    };
     addToCalendarButton: JSX.Element = (
-        <IconButton 
-            tooltip="Add to calendar" 
-            onPointerDown={() => CalendarManager.Instance.open(undefined, this.pinDoc)} 
-            icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} 
-            color={SettingsManager.userColor} />
-    )
+        <IconButton tooltip="Add to calendar" onPointerDown={() => CalendarManager.Instance.open(undefined, this.pinDoc)} icon={<FontAwesomeIcon icon={faCalendarDays as IconLookup} />} color={SettingsManager.userColor} />
+    );
 
     getLinkNoteToDocButton = (docType: string): JSX.Element => {
         return (
@@ -335,8 +319,8 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                     color={SettingsManager.userColor}
                 />
             </div>
-        )
-    }
+        );
+    };
 
     linkNoteToPinOrRoutenButton: JSX.Element = (
         <div ref={this._commentRef}>
@@ -347,16 +331,9 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                 color={SettingsManager.userColor}
             />
         </div>
-    )
-
-    customizePinButton: JSX.Element = (
-        <IconButton 
-            tooltip="Customize pin" 
-            onPointerDown={this.CustomizeClick} 
-            icon={<FontAwesomeIcon icon={faEdit as IconLookup} />} 
-            color={SettingsManager.userColor} 
-        />
-    )
+    );
+
+    customizePinButton: JSX.Element = (<IconButton tooltip="Customize pin" onPointerDown={this.CustomizeClick} icon={<FontAwesomeIcon icon={faEdit as IconLookup} />} color={SettingsManager.userColor} />);
 
     centerOnPinButton: JSX.Element = (
         <IconButton
@@ -365,7 +342,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             icon={<FontAwesomeIcon icon="compress-arrows-alt" />}
             color={SettingsManager.userColor}
         />
-    )
+    );
 
     backButton: JSX.Element = (
         <IconButton
@@ -374,7 +351,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             icon={<FontAwesomeIcon icon={faArrowLeft as IconLookup} />}
             color={SettingsManager.userColor}
         />
-    )
+    );
 
     addRouteButton: JSX.Element = (
         <IconButton
@@ -383,7 +360,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             icon={<FontAwesomeIcon icon={faAdd as IconLookup} />}
             color={SettingsManager.userColor}
         />
-    )
+    );
 
     getDeleteButton = (type: string) => {
         return (
@@ -393,17 +370,10 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
                 icon={<FontAwesomeIcon icon="trash-alt" />}
                 color={SettingsManager.userColor}
             />
-        )
-    }
+        );
+    };
 
-    animateRouteButton: JSX.Element = (
-        <IconButton 
-            tooltip="Animate route" 
-            onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} 
-            icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} 
-            color={SettingsManager.userColor} 
-        />
-    )
+    animateRouteButton: JSX.Element = (<IconButton tooltip="Animate route" onPointerDown={() => this.OpenAnimationPanel(this.routeDoc)} icon={<FontAwesomeIcon icon={faRoute as IconLookup} />} color={SettingsManager.userColor} />);
 
     revertToOriginalMarkerButton = (
         <IconButton
@@ -412,7 +382,7 @@ export class MapAnchorMenu extends AntimodeMenu<AntimodeMenuProps> {
             icon={<FontAwesomeIcon icon={faArrowsRotate as IconLookup} />}
             color={SettingsManager.userColor}
         />
-    )
+    );
 
     render() {
         const buttons = (
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 7db139d74..ffd52fb0e 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -1,8 +1,17 @@
+import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Checkbox, FormControlLabel, TextField } from '@mui/material';
+import * as turf from '@turf/turf';
 import { IconButton, Size, Type } from 'browndash-components';
+import * as d3 from 'd3';
+import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson';
+import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl';
 import { IReactionDisposer, ObservableMap, action, autorun, computed, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { CirclePicker, ColorResult } from 'react-color';
+import { Layer, MapProvider, MapRef, Map as MapboxMap, Marker, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl';
+import { MarkerEvent } from 'react-map-gl/dist/esm/types';
 import { Utils, emptyFunction, setupMoveUpEvents } from '../../../../Utils';
 import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
 import { DocCss, Highlight } from '../../../../fields/DocSymbols';
@@ -22,22 +31,13 @@ import { DocumentView } from '../DocumentView';
 import { FieldView, FieldViewProps } from '../FieldView';
 import { FormattedTextBox } from '../formattedText/FormattedTextBox';
 import { PinProps, PresBox } from '../trails';
-import { MapAnchorMenu } from './MapAnchorMenu';
-import { ControlPosition, Layer, MapProvider, MapRef, Map as MapboxMap, Marker, MarkerProps, Source, ViewState, ViewStateChangeEvent } from 'react-map-gl';
-import './MapBox.scss';
-// import { GeocoderControl } from './GeocoderControl';
-import { IconLookup, faCircleXmark, faGear, faPause, faPlay, faRotate } from '@fortawesome/free-solid-svg-icons';
-import { Checkbox, FormControlLabel, TextField } from '@mui/material';
-import * as turf from '@turf/turf';
-import * as d3 from 'd3';
-import { Feature, FeatureCollection, GeoJsonProperties, Geometry, LineString, Position } from 'geojson';
-import mapboxgl, { LngLat, LngLatBoundsLike, MapLayerMouseEvent } from 'mapbox-gl';
-import { CirclePicker, ColorResult } from 'react-color';
-import { MarkerEvent } from 'react-map-gl/dist/esm/types';
 import { fastSpeedIcon, mediumSpeedIcon, slowSpeedIcon } from './AnimationSpeedIcons';
 import { AnimationSpeed, AnimationStatus, AnimationUtility } from './AnimationUtility';
+import { MapAnchorMenu } from './MapAnchorMenu';
+import './MapBox.scss';
 import { MapboxApiUtility, TransportationType } from './MapboxApiUtility';
 import { MarkerIcons } from './MarkerIcons';
+// import { GeocoderControl } from './GeocoderControl';
 
 // amongus
 /**
@@ -480,7 +480,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     };
 
     // The pin that is selected
-    @observable selectedPinOrRoute: Doc | undefined;
+    @observable selectedPinOrRoute: Doc | undefined = undefined;
 
     @action
     deselectPinOrRoute = () => {
@@ -650,7 +650,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
 
     @action
     deleteSelectedPinOrRoute = undoable(() => {
-        console.log('deleting')
+        console.log('deleting');
         if (this.selectedPinOrRoute) {
             // Removes filter
             Doc.setDocFilter(this.Document, 'latitude', this.selectedPinOrRoute.latitude, 'remove');
@@ -677,15 +677,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             this.temporaryRouteSource = {
                 type: 'FeatureCollection',
                 features: [],
-            }
-        })
-
+            };
+        });
 
         document.removeEventListener('pointerdown', this.tryHideMapAnchorMenu, true);
     };
 
-   
-
     @action
     centerOnSelectedPin = () => {
         if (this.selectedPinOrRoute) {
@@ -882,8 +879,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
             }
             this.temporaryRouteSource = {
                 type: 'FeatureCollection',
-                features: []
-            }
+                features: [],
+            };
             MapAnchorMenu.Instance.fadeOut(true);
             return mapRoute;
         }
@@ -994,8 +991,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
     };
 
-
-
     /**
      * Makes a reverse geocoding API call to retrieve features corresponding to a map click (based on longitude
      * and latitude). Sets the search results accordingly.
@@ -1388,7 +1383,6 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
         }
     };
 
-
     getRouteAnimationOptions = (): JSX.Element => {
         return (
             <>
@@ -1423,20 +1417,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                 <>
                     <div className="animation-suboptions">
                         <div>|</div>
-                        <FormControlLabel
-                            className="first-person-label"
-                            label="1st person animation:"
-                            labelPlacement="start"
-                            control={<Checkbox color="success" checked={this.isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />}
-                        />
+                        <FormControlLabel className="first-person-label" label="1st person animation:" labelPlacement="start" control={<Checkbox color="success" checked={this.isStreetViewAnimation} onChange={this.toggleIsStreetViewAnimation} />} />
                         <div id="divider">|</div>
                         <IconButton tooltip={this.animationSpeedTooltipText} onPointerDown={this.updateAnimationSpeed} icon={this.animationSpeedIcon} size={Size.MEDIUM} />
                         <div id="divider">|</div>
-                        <div style={{display: 'flex', alignItems: 'center'}}>
+                        <div style={{ display: 'flex', alignItems: 'center' }}>
                             <div>Select Line Color: </div>
-                            <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={(color:any) => this.setAnimationLineColor(color)} />
+                            <CirclePicker circleSize={12} circleSpacing={5} width="100%" colors={['#ffff00', '#03a9f4', '#ff0000', '#ff5722', '#000000', '#673ab7']} onChange={(color: any) => this.setAnimationLineColor(color)} />
                         </div>
-                        
                     </div>
                 </>
             </>
@@ -1478,7 +1466,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     onBearingChange = (e: React.ChangeEvent<HTMLInputElement>) => {
         const bearing = parseInt(e.target.value);
         if (!isNaN(bearing) && this._mapRef.current) {
-            console.log('bearing change')
+            console.log('bearing change');
             const fixedBearing = Math.max(0, Math.min(360, bearing));
             this._mapRef.current.setBearing(fixedBearing);
             this.dataDoc.map_bearing = fixedBearing;
@@ -1489,7 +1477,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     onPitchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
         const pitch = parseInt(e.target.value);
         if (!isNaN(pitch) && this._mapRef.current) {
-            console.log('pitch change')
+            console.log('pitch change');
             const fixedPitch = Math.max(0, Math.min(85, pitch));
             this._mapRef.current.setPitch(fixedPitch);
             this.dataDoc.map_pitch = fixedPitch;
@@ -1648,7 +1636,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
                         <MapboxMap
                             ref={this._mapRef}
                             mapboxAccessToken={MAPBOX_ACCESS_TOKEN}
-                            viewState={(this.isAnimating || this.routeToAnimate) ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }}
+                            viewState={this.isAnimating || this.routeToAnimate ? undefined : { ...this.mapboxMapViewState, width: NumCast(this.layoutDoc._width), height: NumCast(this.layoutDoc._height) }}
                             mapStyle={this.dataDoc.map_style ? StrCast(this.dataDoc.map_style) : 'mapbox://styles/mapbox/streets-v11'}
                             style={{
                                 position: 'absolute',
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx
index fdd8285d5..1dbbbb633 100644
--- a/src/client/views/nodes/MapBox/MapBox2.tsx
+++ b/src/client/views/nodes/MapBox/MapBox2.tsx
@@ -87,7 +87,7 @@
 //     private _dropDisposer?: DragManager.DragDropDisposer;
 //     private _disposers: { [name: string]: IReactionDisposer } = {};
 //     private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
-//     @observable private _overlayAnnoInfo: Opt<Doc>;
+//     @observable private _overlayAnnoInfo: Opt<Doc> = undefined;
 //     showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno));
 //     public static LayoutString(fieldKey: string) {
 //         return FieldView.LayoutString(MapBox2, fieldKey);
diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
index 6a14427c0..70037f29c 100644
--- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
+++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
@@ -1,33 +1,31 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import BingMapsReact from 'bingmaps-react';
 import { Button, EditableText, IconButton, Type } from 'browndash-components';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
+import { IReactionDisposer, ObservableMap, action, computed, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { MapProvider, Map as MapboxMap } from 'react-map-gl';
+import { Utils, emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
 import { Doc, DocListCast, Field, LinkedTo, Opt } from '../../../../fields/Doc';
 import { DocCss, Highlight } from '../../../../fields/DocSymbols';
-import { Id } from '../../../../fields/FieldSymbols';
 import { DocCast, NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, setupMoveUpEvents, Utils } from '../../../../Utils';
-import { Docs, DocUtils } from '../../../documents/Documents';
 import { DocumentType } from '../../../documents/DocumentTypes';
+import { DocUtils, Docs } from '../../../documents/Documents';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { DragManager } from '../../../util/DragManager';
 import { LinkManager } from '../../../util/LinkManager';
 import { SnappingManager } from '../../../util/SnappingManager';
 import { Transform } from '../../../util/Transform';
-import { undoable, UndoManager } from '../../../util/UndoManager';
-import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
+import { UndoManager, undoable } from '../../../util/UndoManager';
 import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
-import { Colors } from '../../global/globalEnums';
 import { SidebarAnnos } from '../../SidebarAnnos';
+import { MarqueeOptionsMenu } from '../../collections/collectionFreeForm';
+import { Colors } from '../../global/globalEnums';
 import { DocumentView } from '../DocumentView';
 import { FieldView, FieldViewProps } from '../FieldView';
+import { MapAnchorMenu } from '../MapBox/MapAnchorMenu';
 import { FormattedTextBox } from '../formattedText/FormattedTextBox';
 import { PinProps, PresBox } from '../trails';
 import './MapBox.scss';
-import { MapAnchorMenu } from '../MapBox/MapAnchorMenu';
-import { MapProvider, Map as MapboxMap } from 'react-map-gl';
 
 // amongus
 /**
@@ -351,7 +349,7 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<ViewBoxAnnotata
     }, 'createpin');
 
     // The pin that is selected
-    @observable selectedPin: Doc | undefined;
+    @observable selectedPin: Doc | undefined = undefined;
 
     @action
     deselectPin = () => {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 733febd2d..7f1d6b049 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -48,7 +48,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
     private _sidebarRef = React.createRef<SidebarAnnos>();
 
     @observable private _searching: boolean = false;
-    @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
+    @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy> = undefined;
     @observable private _pageControls = false;
 
     @computed get pdfUrl() {
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
index e75b1ab6f..135db64e0 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationBox.tsx
@@ -6,8 +6,9 @@ import QuestionMarkIcon from '@mui/icons-material/QuestionMark';
 import ReplayIcon from '@mui/icons-material/Replay';
 import { Box, Button, Checkbox, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, FormControl, FormControlLabel, FormGroup, IconButton, LinearProgress, Stack } from '@mui/material';
 import Typography from '@mui/material/Typography';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { IReactionDisposer, action, computed, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { NumListCast } from '../../../../fields/Doc';
 import { List } from '../../../../fields/List';
 import { BoolCast, NumCast, StrCast } from '../../../../fields/Types';
@@ -19,7 +20,6 @@ import questions from './PhysicsSimulationQuestions.json';
 import tutorials from './PhysicsSimulationTutorial.json';
 import Wall from './PhysicsSimulationWall';
 import Weight from './PhysicsSimulationWeight';
-import * as React from 'react';
 
 interface IWallProps {
     length: number;
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
index f5077a07e..3b232ddd0 100644
--- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
+++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx
@@ -1,7 +1,7 @@
 import { computed, IReactionDisposer, makeObservable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
-import './PhysicsSimulationBox.scss';
 import * as React from 'react';
+import './PhysicsSimulationBox.scss';
 
 interface IWallProps {
     length: number;
diff --git a/src/client/views/nodes/RadialMenu.tsx b/src/client/views/nodes/RadialMenu.tsx
index 061a46f03..3b2fc033d 100644
--- a/src/client/views/nodes/RadialMenu.tsx
+++ b/src/client/views/nodes/RadialMenu.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
 import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import './RadialMenu.scss';
 import { RadialMenuItem, RadialMenuProps } from './RadialMenuItem';
 
diff --git a/src/client/views/nodes/RadialMenuItem.tsx b/src/client/views/nodes/RadialMenuItem.tsx
index c931202f1..10a90befd 100644
--- a/src/client/views/nodes/RadialMenuItem.tsx
+++ b/src/client/views/nodes/RadialMenuItem.tsx
@@ -1,7 +1,7 @@
-import * as React from 'react';
 import { IconProp } from '@fortawesome/fontawesome-svg-core';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { UndoManager } from '../../util/UndoManager';
 
 export interface RadialMenuProps {
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index f01642236..658cfb1ca 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -8,15 +8,15 @@ import { List } from '../../../../fields/List';
 import { BoolCast, DocCast } from '../../../../fields/Types';
 import { VideoField } from '../../../../fields/URLField';
 import { Upload } from '../../../../server/SharedMediaTypes';
-import { Docs } from '../../../documents/Documents';
 import { DocumentType } from '../../../documents/DocumentTypes';
+import { Docs } from '../../../documents/Documents';
 import { DocumentManager } from '../../../util/DocumentManager';
 import { DragManager } from '../../../util/DragManager';
 import { ScriptingGlobals } from '../../../util/ScriptingGlobals';
 import { Presentation } from '../../../util/TrackMovements';
 import { undoBatch } from '../../../util/UndoManager';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
 import { ViewBoxBaseComponent } from '../../DocComponent';
+import { CollectionFreeFormView } from '../../collections/collectionFreeForm/CollectionFreeFormView';
 import { media_state } from '../AudioBox';
 import { FieldView, FieldViewProps } from '../FieldView';
 import { VideoBox } from '../VideoBox';
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index d5d31b407..79ed69cdd 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -1,5 +1,5 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import * as React from 'react';
 // import { Canvas } from '@react-three/fiber';
 import { computed, makeObservable, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index 7e7eaee45..8e506ec64 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -2,25 +2,23 @@ let ReactTextareaAutocomplete = require('@webscopeio/react-textarea-autocomplete
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
+import { returnAlways, returnEmptyString } from '../../../Utils';
 import { Doc } from '../../../fields/Doc';
 import { List } from '../../../fields/List';
 import { listSpec } from '../../../fields/Schema';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
 import { TraceMobx } from '../../../fields/util';
-import { returnAlways, returnEmptyString, returnTrue } from '../../../Utils';
 import { DragManager } from '../../util/DragManager';
-import { InteractionUtils } from '../../util/InteractionUtils';
+import { ScriptManager } from '../../util/ScriptManager';
 import { CompileScript, ScriptParam } from '../../util/Scripting';
 import { ScriptingGlobals } from '../../util/ScriptingGlobals';
-import { ScriptManager } from '../../util/ScriptManager';
 import { ContextMenu } from '../ContextMenu';
 import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
 import { EditableView } from '../EditableView';
-import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import { OverlayView } from '../OverlayView';
+import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import { DocumentIconContainer } from './DocumentIcon';
-import { DocFocusOptions, DocumentView } from './DocumentView';
 import './ScriptingBox.scss';
 const _global = (window /* browser */ || global) /* node */ as any;
 
diff --git a/src/client/views/nodes/TaskCompletedBox.tsx b/src/client/views/nodes/TaskCompletedBox.tsx
index 9aab8c5a9..c9e15d314 100644
--- a/src/client/views/nodes/TaskCompletedBox.tsx
+++ b/src/client/views/nodes/TaskCompletedBox.tsx
@@ -1,15 +1,15 @@
-import * as React from 'react';
+import { Fade } from '@mui/material';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import './TaskCompletedBox.scss';
-import { observable, action } from 'mobx';
-import { Fade } from '@mui/material';
 
 @observer
 export class TaskCompletionBox extends React.Component<{}> {
     @observable public static taskCompleted: boolean = false;
     @observable public static popupX: number = 500;
     @observable public static popupY: number = 150;
-    @observable public static textDisplayed: string;
+    @observable public static textDisplayed: string = '';
 
     @action
     public static toggleTaskCompleted = () => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index f205dbd56..8e9cfe3d7 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -74,8 +74,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
         this._props.setContentView?.(this);
     }
 
-    @observable _stackedTimeline: any; // CollectionStackedTimeline ref
-    @observable static _nativeControls: boolean; // default html controls
+    @observable _stackedTimeline: any = undefined; // CollectionStackedTimeline ref
+    @observable static _nativeControls: boolean = false; // default html controls
     @observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
     @observable _screenCapture = false;
     @observable _clicking = false; // used for transition between showing/hiding timeline
@@ -86,7 +86,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
     @observable _finished: boolean = false; // has playback reached end of clip
     @observable _volume: number = 1;
     @observable _muted: boolean = false;
-    @observable _controlsTransform?: { X: number; Y: number };
+    @observable _controlsTransform?: { X: number; Y: number } = undefined;
     @observable _controlsVisible: boolean = true;
     @observable _scrubbing: boolean = false;
 
diff --git a/src/client/views/nodes/audio/AudioWaveform.tsx b/src/client/views/nodes/audio/AudioWaveform.tsx
index c034d95ea..3e46ff4e6 100644
--- a/src/client/views/nodes/audio/AudioWaveform.tsx
+++ b/src/client/views/nodes/audio/AudioWaveform.tsx
@@ -7,10 +7,10 @@ import { List } from '../../../../fields/List';
 import { listSpec } from '../../../../fields/Schema';
 import { Cast } from '../../../../fields/Types';
 import { numberRange } from '../../../../Utils';
+import { ObservableReactComponent } from '../../ObservableReactComponent';
 import { Colors } from './../../global/globalEnums';
 import './AudioWaveform.scss';
 import { WaveCanvas } from './WaveCanvas';
-import { ObservableReactComponent } from '../../ObservableReactComponent';
 
 /**
  * AudioWaveform
diff --git a/src/client/views/nodes/calendarBox/CalendarBox.tsx b/src/client/views/nodes/calendarBox/CalendarBox.tsx
index 989feb774..4fb1a7f17 100644
--- a/src/client/views/nodes/calendarBox/CalendarBox.tsx
+++ b/src/client/views/nodes/calendarBox/CalendarBox.tsx
@@ -1,40 +1,35 @@
-import * as React from 'react';
-import { observer } from "mobx-react";
-import { Doc } from "../../../../fields/Doc";
-import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps, ViewBoxBaseComponent } from '../../DocComponent';
-import { FieldView, FieldViewProps } from '../FieldView';
-import { StrCast } from '../../../../fields/Types';
+import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core';
+import dayGridPlugin from '@fullcalendar/daygrid';
+import multiMonthPlugin from '@fullcalendar/multimonth';
 import { makeObservable } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
 import { dateRangeStrToDates } from '../../../../Utils';
-import { Calendar, EventClickArg, EventSourceInput } from '@fullcalendar/core'
-import dayGridPlugin from '@fullcalendar/daygrid'
-import multiMonthPlugin from '@fullcalendar/multimonth'
-import { faListNumeric } from '@fortawesome/free-solid-svg-icons';
+import { Doc } from '../../../../fields/Doc';
+import { StrCast } from '../../../../fields/Types';
+import { ViewBoxBaseComponent } from '../../DocComponent';
+import { FieldView, FieldViewProps } from '../FieldView';
 
 type CalendarView = 'month' | 'multi-month' | 'week';
 
 @observer
-export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
+export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>() {
     public static LayoutString(fieldKey: string = 'calendar') {
         return FieldView.LayoutString(CalendarBox, fieldKey);
     }
 
-    componentDidMount(): void {
-        
-    }
+    componentDidMount(): void {}
 
-    componentWillUnmount(): void {
-        
-    }
+    componentWillUnmount(): void {}
 
-    _calendarRef = React.createRef<HTMLElement>()
+    _calendarRef = React.createRef<HTMLElement>();
 
-    get dateRangeStr (){
+    get dateRangeStr() {
         return StrCast(this.Document.date_range);
     }
 
-    // Choose a calendar view based on the date range 
-    get calendarViewType (): CalendarView {
+    // Choose a calendar view based on the date range
+    get calendarViewType(): CalendarView {
         const [fromDate, toDate] = dateRangeStrToDates(this.dateRangeStr);
 
         if (fromDate.getFullYear() !== toDate.getFullYear() || fromDate.getMonth() !== toDate.getMonth()) return 'multi-month';
@@ -43,92 +38,83 @@ export class CalendarBox extends ViewBoxBaseComponent<FieldViewProps>(){
         return 'week';
     }
 
-    get calendarStartDate () {
-        return this.dateRangeStr.split("|")[0];
+    get calendarStartDate() {
+        return this.dateRangeStr.split('|')[0];
     }
 
-    get calendarToDate () {
-        return this.dateRangeStr.split("|")[1];
+    get calendarToDate() {
+        return this.dateRangeStr.split('|')[1];
     }
 
-    get childDocs (): Doc[] {
+    get childDocs(): Doc[] {
         return this.childDocs; // get all sub docs for a calendar
     }
 
-    docBackgroundColor (type: string): string {
+    docBackgroundColor(type: string): string {
         // TODO: Return a different color based on the event type
         return 'blue';
     }
 
-    get calendarEvents (): EventSourceInput | undefined {
+    get calendarEvents(): EventSourceInput | undefined {
         if (this.childDocs.length === 0) return undefined;
         return this.childDocs.map((doc, idx) => {
             const docTitle = StrCast(doc.title);
             const docDateRange = StrCast(doc.date_range);
             const [startDate, endDate] = dateRangeStrToDates(docDateRange);
             const docType = doc.type;
-            const docDescription = doc.description ? StrCast(doc.description): "";
+            const docDescription = doc.description ? StrCast(doc.description) : '';
 
             return {
                 title: docTitle,
                 start: startDate,
                 end: endDate,
                 allDay: false,
-                classNames:[StrCast(docType)], // will determine the style 
+                classNames: [StrCast(docType)], // will determine the style
                 editable: false, // subject to change in the future
                 backgroundColor: this.docBackgroundColor(StrCast(doc.type)),
                 color: 'white',
                 extendedProps: {
-                    description: docDescription
+                    description: docDescription,
                 },
-                
-            }
-
-        })
+            };
+        });
     }
 
     handleEventClick = (arg: EventClickArg) => {
         // TODO: open popover with event description, option to open CalendarManager and change event date, delete event, etc.
-    }
+    };
 
     calendarEl: HTMLElement = document.getElementById('calendar-box-v1')!;
 
     // https://fullcalendar.io
     get calendar() {
-        return new Calendar(this.calendarEl, 
-            {
-                plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin],
-                headerToolbar: {
-                    left: 'prev,next today',
-                    center: 'title',
-                    right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
-                },
-                initialDate: this.calendarStartDate,
-                navLinks: true,
-                editable: false,
-                displayEventTime: false,
-                displayEventEnd: false,
-                events: this.calendarEvents,
-                eventClick: this.handleEventClick
-            }
-        )
-        
+        return new Calendar(this.calendarEl, {
+            plugins: [this.calendarViewType === 'multi-month' ? multiMonthPlugin : dayGridPlugin],
+            headerToolbar: {
+                left: 'prev,next today',
+                center: 'title',
+                right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek',
+            },
+            initialDate: this.calendarStartDate,
+            navLinks: true,
+            editable: false,
+            displayEventTime: false,
+            displayEventEnd: false,
+            events: this.calendarEvents,
+            eventClick: this.handleEventClick,
+        });
     }
 
-
-    constructor(props: any){
+    constructor(props: any) {
         super(props);
         makeObservable(this);
     }
 
-    render(){
+    render() {
         return (
-            <div className='calendar-box-conatiner'>
-                <div id='calendar-box-v1'>
-
-                </div>
-            </div>  
+            <div className="calendar-box-conatiner">
+                <div id="calendar-box-v1"></div>
+            </div>
         );
-        
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 6332b200d..1002ee403 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -1,17 +1,17 @@
 import { action, IReactionDisposer, observable, reaction } from 'mobx';
 import { observer } from 'mobx-react';
 import { NodeSelection } from 'prosemirror-state';
+import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
 import { Doc } from '../../../../fields/Doc';
 import { Height, Width } from '../../../../fields/DocSymbols';
 import { NumCast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, returnTrue, Utils } from '../../../../Utils';
+import { emptyFunction, returnFalse, Utils } from '../../../../Utils';
 import { DocServer } from '../../../DocServer';
 import { Docs, DocUtils } from '../../../documents/Documents';
 import { Transform } from '../../../util/Transform';
 import { DocFocusOptions, DocumentView } from '../DocumentView';
 import { FormattedTextBox } from './FormattedTextBox';
-import * as React from 'react';
 
 export class DashDocView {
     dom: HTMLSpanElement; // container for label and value
@@ -83,7 +83,7 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
     _disposers: { [name: string]: IReactionDisposer } = {};
     _textBox: FormattedTextBox;
     @observable _dashDoc: Doc | undefined = undefined;
-    @observable _finalLayout: any;
+    @observable _finalLayout: any = undefined;
     @observable _width: number = 0;
     @observable _height: number = 0;
 
diff --git a/src/client/views/nodes/formattedText/EquationView.tsx b/src/client/views/nodes/formattedText/EquationView.tsx
index 331ed1980..7e655531e 100644
--- a/src/client/views/nodes/formattedText/EquationView.tsx
+++ b/src/client/views/nodes/formattedText/EquationView.tsx
@@ -1,14 +1,13 @@
-import EquationEditor from './EquationEditor';
-import { IReactionDisposer, trace } from 'mobx';
+import { IReactionDisposer } from 'mobx';
 import { observer } from 'mobx-react';
 import { TextSelection } from 'prosemirror-state';
+import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
 import { Doc } from '../../../../fields/Doc';
 import { StrCast } from '../../../../fields/Types';
 import './DashFieldView.scss';
+import EquationEditor from './EquationEditor';
 import { FormattedTextBox } from './FormattedTextBox';
-import * as React from 'react';
-import { AnyArray } from 'mongoose';
 
 export class EquationView {
     dom: HTMLDivElement; // container for label and value
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ad2fab8b0..8bf8abafa 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -11,6 +11,7 @@ import { keymap } from 'prosemirror-keymap';
 import { Fragment, Mark, Node, Slice } from 'prosemirror-model';
 import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state';
 import { EditorView } from 'prosemirror-view';
+import * as React from 'react';
 import { BsMarkdownFill } from 'react-icons/bs';
 import { DateField } from '../../../../fields/DateField';
 import { Doc, DocListCast, Field, Opt } from '../../../../fields/Doc';
@@ -70,9 +71,8 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu';
 import { RichTextRules } from './RichTextRules';
 import { schema } from './schema_rts';
 import { SummaryView } from './SummaryView';
-// import * as applyDevTools from 'prosemirror-dev-tools';
-import * as React from 'react';
 export const GoogleRef = 'googleDocId';
+// import * as applyDevTools from 'prosemirror-dev-tools';
 type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void;
 
 export interface FormattedTextBoxProps {}
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index 4881070fd..3b31f2d17 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -32,7 +32,7 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
     private _linkToRef = React.createRef<HTMLInputElement>();
 
     layoutDoc: Doc | undefined;
-    @observable public view?: EditorView;
+    @observable public view?: EditorView = undefined;
     public editorProps: FieldViewProps | undefined;
 
     public _brushMap: Map<string, Set<Mark>> = new Map();
diff --git a/src/client/views/nodes/importBox/ImportElementBox.tsx b/src/client/views/nodes/importBox/ImportElementBox.tsx
index 9dc0c5180..b573f7c48 100644
--- a/src/client/views/nodes/importBox/ImportElementBox.tsx
+++ b/src/client/views/nodes/importBox/ImportElementBox.tsx
@@ -1,13 +1,11 @@
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { returnFalse } from '../../../../Utils';
 import { Doc } from '../../../../fields/Doc';
-import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue } from '../../../../Utils';
-import { Transform } from '../../../util/Transform';
 import { ViewBoxBaseComponent } from '../../DocComponent';
-import { DefaultStyleProvider } from '../../StyleProvider';
-import { DocumentView, DocumentViewInternal } from '../DocumentView';
+import { DocumentView } from '../DocumentView';
 import { FieldView, FieldViewProps } from '../FieldView';
-import * as React from 'react';
 
 @observer
 export class ImportElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index e213b2fc5..0305689e7 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -1,8 +1,8 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { Tooltip } from '@mui/material';
 import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc, DocListCast, FieldResult, NumListCast, Opt, StrListCast } from '../../../../fields/Doc';
 import { Animation } from '../../../../fields/DocSymbols';
 import { Copy, Id } from '../../../../fields/FieldSymbols';
@@ -24,7 +24,7 @@ import { SerializationHelper } from '../../../util/SerializationHelper';
 import { SettingsManager } from '../../../util/SettingsManager';
 import { undoBatch, UndoManager } from '../../../util/UndoManager';
 import { CollectionDockingView } from '../../collections/CollectionDockingView';
-import { CollectionFreeFormView, computeTimelineLayout, MarqueeViewBounds } from '../../collections/collectionFreeForm';
+import { CollectionFreeFormView, MarqueeViewBounds } from '../../collections/collectionFreeForm';
 import { CollectionStackedTimeline } from '../../collections/CollectionStackedTimeline';
 import { CollectionView } from '../../collections/CollectionView';
 import { TreeView } from '../../collections/TreeView';
@@ -83,12 +83,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
     _batch: UndoManager.Batch | undefined = undefined; // undo batch for dragging sliders which generate multiple scene edit events as the cursor moves
     _keyTimer: NodeJS.Timeout | undefined; // timer for turning off transition flag when key frame change has completed.  Need to clear this if you do a second navigation before first finishes, or else first timer can go off during second naviation.
     _unmounting = false; // flag that view is unmounting used to block RemFromMap from deleting things
+    _presTimer: NodeJS.Timeout | undefined;
 
     @observable public static Instance: PresBox;
 
     @observable _isChildActive = false;
     @observable _moveOnFromAudio: boolean = true;
-    @observable _presTimer!: NodeJS.Timeout;
 
     @observable _eleArray: HTMLElement[] = [];
     @observable _dragArray: HTMLElement[] = [];
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index cf19ff6bc..5ea9e9979 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,18 +1,17 @@
-import * as React from 'react';
 import { action, computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
 import { List } from '../../../fields/List';
 import { BoolCast, Cast, DocCast, NumCast, StrCast } from '../../../fields/Types';
 import { LinkFollower } from '../../util/LinkFollower';
+import { LinkManager } from '../../util/LinkManager';
 import { undoBatch } from '../../util/UndoManager';
 import { OpenWhere } from '../nodes/DocumentView';
 import { FieldViewProps } from '../nodes/FieldView';
 import { AnchorMenu } from './AnchorMenu';
 import './Annotation.scss';
-import { LinkManager } from '../../util/LinkManager';
-import { Rect } from 'react-measure';
 
 interface IAnnotationProps extends FieldViewProps {
     anno: Doc;
diff --git a/src/client/views/pdf/GPTPopup/GPTPopup.tsx b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
index db21d9a3d..da8a88803 100644
--- a/src/client/views/pdf/GPTPopup/GPTPopup.tsx
+++ b/src/client/views/pdf/GPTPopup/GPTPopup.tsx
@@ -1,20 +1,20 @@
-import * as React from 'react';
-import './GPTPopup.scss';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { Button, IconButton, Type } from 'browndash-components';
 import { action, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { CgClose } from 'react-icons/cg';
 import ReactLoading from 'react-loading';
 import { TypeAnimation } from 'react-type-animation';
+import { Utils } from '../../../../Utils';
 import { Doc } from '../../../../fields/Doc';
-import { DocUtils, Docs } from '../../../documents/Documents';
-import { Button, IconButton, Type } from 'browndash-components';
 import { NumCast, StrCast } from '../../../../fields/Types';
-import { CgClose } from 'react-icons/cg';
-import { AnchorMenu } from '../AnchorMenu';
-import { gptImageCall } from '../../../apis/gpt/GPT';
 import { Networking } from '../../../Network';
-import { Utils } from '../../../../Utils';
+import { gptImageCall } from '../../../apis/gpt/GPT';
+import { DocUtils, Docs } from '../../../documents/Documents';
 import { ObservableReactComponent } from '../../ObservableReactComponent';
+import { AnchorMenu } from '../AnchorMenu';
+import './GPTPopup.scss';
 
 export enum GPTPopupMode {
     SUMMARY,
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index e342c25b3..b6d027d30 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -302,7 +302,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> {
         }
     };
 
-    @observable private _scrollTimer: any;
+    @observable private _scrollTimer: any = undefined;
 
     onScroll = (e: React.UIEvent<HTMLElement>) => {
         if (this._mainCont.current && !this._forcedScroll) {
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index ccfccb771..14187833f 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -2,24 +2,23 @@ import { Tooltip } from '@mui/material';
 import { action, computed, makeObservable, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Doc, DocListCast, DocListCastAsync, Field, Opt } from '../../../fields/Doc';
+import { Doc, DocListCastAsync, Field } from '../../../fields/Doc';
 import { DirectLinks } from '../../../fields/DocSymbols';
 import { Id } from '../../../fields/FieldSymbols';
 import { DocCast, StrCast } from '../../../fields/Types';
-import { DocUtils } from '../../documents/Documents';
 import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/Documents';
 import { DocumentManager } from '../../util/DocumentManager';
 import { LinkManager } from '../../util/LinkManager';
+import { SearchUtil } from '../../util/SearchUtil';
+import { SettingsManager } from '../../util/SettingsManager';
 import { undoBatch } from '../../util/UndoManager';
-import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { ViewBoxBaseComponent } from '../DocComponent';
+import { CollectionDockingView } from '../collections/CollectionDockingView';
+import { IRecommendation, Recommendation } from '../newlightbox/components';
+import { fetchRecommendations } from '../newlightbox/utils';
 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';
-import { SettingsManager } from '../../util/SettingsManager';
-import { SearchUtil } from '../../util/SearchUtil';
 
 const DAMPENING_FACTOR = 0.9;
 const MAX_ITERATIONS = 25;
diff --git a/src/client/views/selectedDoc/SelectedDocView.tsx b/src/client/views/selectedDoc/SelectedDocView.tsx
index 39e778b76..daacb368b 100644
--- a/src/client/views/selectedDoc/SelectedDocView.tsx
+++ b/src/client/views/selectedDoc/SelectedDocView.tsx
@@ -1,14 +1,14 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { ListBox } from 'browndash-components';
 import { computed } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { emptyFunction } from '../../../Utils';
 import { Doc } from '../../../fields/Doc';
 import { StrCast } from '../../../fields/Types';
 import { DocumentManager } from '../../util/DocumentManager';
-import { DocFocusOptions } from '../nodes/DocumentView';
-import { emptyFunction } from '../../../Utils';
 import { SettingsManager } from '../../util/SettingsManager';
+import { DocFocusOptions } from '../nodes/DocumentView';
 
 export interface SelectedDocViewProps {
     selectedDocs: Doc[];
diff --git a/src/client/views/topbar/TopBar.tsx b/src/client/views/topbar/TopBar.tsx
index 0f3487cd1..575d5849e 100644
--- a/src/client/views/topbar/TopBar.tsx
+++ b/src/client/views/topbar/TopBar.tsx
@@ -16,15 +16,15 @@ import { ReportManager } from '../../util/reportManager/ReportManager';
 import { ServerStats } from '../../util/ServerStats';
 import { SettingsManager } from '../../util/SettingsManager';
 import { SharingManager } from '../../util/SharingManager';
+import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
 import { CollectionDockingView } from '../collections/CollectionDockingView';
 import { CollectionLinearView } from '../collections/collectionLinear';
 import { DashboardView } from '../DashboardView';
 import { Colors } from '../global/globalEnums';
-import { DocumentView, DocumentViewInternal } from '../nodes/DocumentView';
+import { DocumentViewInternal } from '../nodes/DocumentView';
 import { DefaultStyleProvider } from '../StyleProvider';
 import './TopBar.scss';
-import { SnappingManager } from '../../util/SnappingManager';
 
 /**
  * ABOUT: This is the topbar in Dash, which included the current Dashboard as well as access to information on the user
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
index f1739a41a..94458563e 100644
--- a/src/client/views/webcam/DashWebRTCVideo.tsx
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -3,16 +3,15 @@ import { faPhoneSlash, faSync } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { Doc } from '../../../fields/Doc';
 import { InkTool } from '../../../fields/InkField';
+import { SnappingManager } from '../../util/SnappingManager';
 import '../../views/nodes/WebBox.scss';
 import { CollectionFreeFormDocumentViewProps } from '../nodes/CollectionFreeFormDocumentView';
-import { DocumentView } from '../nodes/DocumentView';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
 import './DashWebRTCVideo.scss';
 import { hangup, initialize, refreshVideos } from './WebCamLogic';
-import * as React from 'react';
-import { SnappingManager } from '../../util/SnappingManager';
 
 /**
  * This models the component that will be rendered, that can be used as a doc that will reflect the video cams.
diff --git a/src/debug/Repl.tsx b/src/debug/Repl.tsx
index b8081648f..a9f7c085f 100644
--- a/src/debug/Repl.tsx
+++ b/src/debug/Repl.tsx
@@ -1,13 +1,13 @@
+import { computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom/client';
-import { observer } from 'mobx-react';
-import { observable, computed } from 'mobx';
+import { DocServer } from '../client/DocServer';
+import { resolvedPorts } from '../client/util/CurrentUserUtils';
 import { CompileScript } from '../client/util/Scripting';
-import { makeInterface } from '../fields/Schema';
 import { ObjectField } from '../fields/ObjectField';
 import { RefField } from '../fields/RefField';
-import { DocServer } from '../client/DocServer';
-import { resolvedPorts } from '../client/util/CurrentUserUtils';
+import { makeInterface } from '../fields/Schema';
 
 @observer
 class Repl extends React.Component {
diff --git a/src/debug/Viewer.tsx b/src/debug/Viewer.tsx
index 02038c426..f46adef77 100644
--- a/src/debug/Viewer.tsx
+++ b/src/debug/Viewer.tsx
@@ -1,19 +1,19 @@
-import { action, configure, observable, ObservableMap, Lambda } from 'mobx';
+import { action, configure, observable } from 'mobx';
+import { observer } from 'mobx-react';
 import * as React from 'react';
 import * as ReactDOM from 'react-dom';
-import { observer } from 'mobx-react';
-import { Doc, Field, FieldResult, Opt } from '../fields/Doc';
 import { DocServer } from '../client/DocServer';
+import { resolvedPorts } from '../client/util/CurrentUserUtils';
+import { CompileScript } from '../client/util/Scripting';
+import { EditableView } from '../client/views/EditableView';
+import CursorField from '../fields/CursorField';
+import { DateField } from '../fields/DateField';
+import { Doc, Field, FieldResult } from '../fields/Doc';
 import { Id } from '../fields/FieldSymbols';
 import { List } from '../fields/List';
-import { URLField } from '../fields/URLField';
-import { EditableView } from '../client/views/EditableView';
-import { CompileScript } from '../client/util/Scripting';
 import { RichTextField } from '../fields/RichTextField';
-import { DateField } from '../fields/DateField';
 import { ScriptField } from '../fields/ScriptField';
-import CursorField from '../fields/CursorField';
-import { resolvedPorts } from '../client/util/CurrentUserUtils';
+import { URLField } from '../fields/URLField';
 
 DateField;
 URLField;
diff --git a/src/fields/CursorField.ts b/src/fields/CursorField.ts
index 46f5a8e1c..84917ae53 100644
--- a/src/fields/CursorField.ts
+++ b/src/fields/CursorField.ts
@@ -1,8 +1,7 @@
-import { ObjectField } from './ObjectField';
-import { observable } from 'mobx';
+import { createSimpleSchema, object, serializable } from 'serializr';
 import { Deserializable } from '../client/util/SerializationHelper';
-import { serializable, createSimpleSchema, object, date } from 'serializr';
-import { FieldChanged, ToScriptString, ToString, Copy } from './FieldSymbols';
+import { Copy, FieldChanged, ToScriptString, ToString } from './FieldSymbols';
+import { ObjectField } from './ObjectField';
 
 export type CursorPosition = {
     x: number;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 8903a9f97..9dc3c173d 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -265,8 +265,8 @@ export class Doc extends RefField {
     @observable public [DocAcl]: { [key: string]: symbol } = {};
     @observable public [DocCss]: number = 0; // incrementer denoting a change to CSS layout
     @observable public [DirectLinks] = new ObservableSet<Doc>();
-    @observable public [AudioPlay]: any; // meant to store sound object from Howl
-    @observable public [Animation]: Opt<Doc>;
+    @observable public [AudioPlay]: any = undefined; // meant to store sound object from Howl
+    @observable public [Animation]: Opt<Doc> = undefined;
     @observable public [Highlight]: boolean = false;
     @observable public [Brushed]: boolean = false;
     @observable public [DocViews] = new ObservableSet<DocumentView>();
diff --git a/src/fields/List.ts b/src/fields/List.ts
index 8c8ff1ea3..b8ad552d2 100644
--- a/src/fields/List.ts
+++ b/src/fields/List.ts
@@ -2,7 +2,7 @@ import { action, computed, makeObservable, observable } from 'mobx';
 import { alias, list, serializable } from 'serializr';
 import { DocServer } from '../client/DocServer';
 import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { afterDocDeserialize, autoObject, Deserializable } from '../client/util/SerializationHelper';
+import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper';
 import { Field } from './Doc';
 import { FieldTuples, Self, SelfProxy } from './DocSymbols';
 import { Copy, FieldChanged, Parent, ToScriptString, ToString } from './FieldSymbols';
@@ -11,7 +11,7 @@ import { ProxyField } from './Proxy';
 import { RefField } from './RefField';
 import { listSpec } from './Schema';
 import { Cast } from './Types';
-import { deleteProperty, getter, setter, containedFieldChangedHandler } from './util';
+import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util';
 
 function toObjectField(field: Field) {
     return field instanceof RefField ? new ProxyField(field) : field;
@@ -102,8 +102,8 @@ class ListImpl<T extends Field> extends ObjectField {
                 items.length === 0 && deleteCount
                     ? { op: '$remFromSet', items: removed, hint: { start, deleteCount }, length: list.__fieldTuples.length }
                     : items.length && !deleteCount && start === list.__fieldTuples.length
-                    ? { op: '$addToSet', items, length: list.__fieldTuples.length }
-                    : undefined
+                      ? { op: '$addToSet', items, length: list.__fieldTuples.length }
+                      : undefined
             );
             return res.map(toRealField);
         }),
diff --git a/src/fields/Proxy.ts b/src/fields/Proxy.ts
index c076f5fe1..3a46e3581 100644
--- a/src/fields/Proxy.ts
+++ b/src/fields/Proxy.ts
@@ -1,12 +1,12 @@
-import { Deserializable } from '../client/util/SerializationHelper';
-import { Field, FieldWaiting, Opt } from './Doc';
+import { action, computed, observable, runInAction } from 'mobx';
 import { primitive, serializable } from 'serializr';
-import { observable, action, runInAction, computed } from 'mobx';
 import { DocServer } from '../client/DocServer';
-import { RefField } from './RefField';
-import { ObjectField } from './ObjectField';
-import { Id, Copy, ToScriptString, ToString, ToValue } from './FieldSymbols';
 import { scriptingGlobal } from '../client/util/ScriptingGlobals';
+import { Deserializable } from '../client/util/SerializationHelper';
+import { Field, FieldWaiting, Opt } from './Doc';
+import { Copy, Id, ToScriptString, ToString, ToValue } from './FieldSymbols';
+import { ObjectField } from './ObjectField';
+import { RefField } from './RefField';
 
 function deserializeProxy(field: any) {
     if (!field.cache.field) {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 545fe4478..b73520999 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,11 +1,11 @@
 import { $mobx, action, observable, runInAction, trace } from 'mobx';
 import { computedFn } from 'mobx-utils';
+import { returnZero } from '../Utils';
 import { DocServer } from '../client/DocServer';
 import { LinkManager } from '../client/util/LinkManager';
 import { SerializationHelper } from '../client/util/SerializationHelper';
 import { UndoManager } from '../client/util/UndoManager';
-import { returnZero } from '../Utils';
-import { aclLevel, Doc, DocListCast, Field, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, updateCachedAcls } from './Doc';
+import { Doc, DocListCast, Field, FieldResult, HierarchyMapping, ReverseHierarchyMap, StrListCast, aclLevel, updateCachedAcls } from './Doc';
 import { AclAdmin, AclAugment, AclEdit, AclPrivate, DocAcl, DocData, DocLayout, FieldKeys, ForceServerWrite, Height, Initializing, SelfProxy, UpdatingFromServer, Width } from './DocSymbols';
 import { FieldChanged, Id, Parent, ToValue } from './FieldSymbols';
 import { List } from './List';
diff --git a/src/mobile/ImageUpload.tsx b/src/mobile/ImageUpload.tsx
index d2598c2db..e333e6a2e 100644
--- a/src/mobile/ImageUpload.tsx
+++ b/src/mobile/ImageUpload.tsx
@@ -1,19 +1,19 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import * as rp from 'request-promise';
+import { Utils } from '../Utils';
 import { DocServer } from '../client/DocServer';
-import { Docs } from '../client/documents/Documents';
 import { Networking } from '../client/Network';
+import { Docs } from '../client/documents/Documents';
 import { MainViewModal } from '../client/views/MainViewModal';
 import { Doc, Opt } from '../fields/Doc';
 import { List } from '../fields/List';
 import { listSpec } from '../fields/Schema';
 import { Cast } from '../fields/Types';
-import { Utils } from '../Utils';
 import './ImageUpload.scss';
 import { MobileInterface } from './MobileInterface';
-import * as React from 'react';
 const { default: { DFLT_IMAGE_NATIVE_DIM } } = require('../client/views/global/globalCssVariables.module.scss'); // prettier-ignore
 export interface ImageUploadProps {
     Document: Doc; // Target document for upload (upload location)
diff --git a/src/mobile/MobileInkOverlay.tsx b/src/mobile/MobileInkOverlay.tsx
index 2e595e4bc..23e19585a 100644
--- a/src/mobile/MobileInkOverlay.tsx
+++ b/src/mobile/MobileInkOverlay.tsx
@@ -1,6 +1,6 @@
-import * as React from 'react';
 import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
 import { DocServer } from '../client/DocServer';
 import { DragManager } from '../client/util/DragManager';
 import { Doc } from '../fields/Doc';
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index bdd657575..e3d8f9394 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -1,52 +1,33 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
 import {
-    faTasks,
-    faReply,
-    faQuoteLeft,
-    faHandPointLeft,
-    faFolderOpen,
+    faAddressCard,
+    faAlignLeft,
+    faAlignRight,
     faAngleDoubleLeft,
-    faExternalLinkSquareAlt,
-    faMobile,
-    faThLarge,
-    faWindowClose,
-    faEdit,
-    faTrashAlt,
-    faPalette,
     faAngleRight,
+    faArrowDown,
+    faArrowLeft,
+    faArrowRight,
+    faArrowUp,
+    faArrowsAltH,
+    faAsterisk,
+    faBars,
     faBell,
-    faTrash,
+    faBolt,
+    faBook,
+    faBrain,
+    faBullseye,
+    faCalculator,
     faCamera,
-    faExpand,
     faCaretDown,
     faCaretLeft,
     faCaretRight,
     faCaretSquareDown,
     faCaretSquareRight,
-    faArrowsAltH,
-    faPlus,
-    faMinus,
-    faTerminal,
-    faToggleOn,
-    faFile as fileSolid,
-    faExternalLinkAlt,
-    faLocationArrow,
-    faSearch,
-    faFileDownload,
-    faStop,
-    faCalculator,
-    faWindowMaximize,
-    faAddressCard,
-    faQuestionCircle,
-    faArrowLeft,
-    faArrowRight,
-    faArrowDown,
-    faArrowUp,
-    faBolt,
-    faBullseye,
     faCaretUp,
     faCat,
     faCheck,
+    faChevronLeft,
     faChevronRight,
     faClipboard,
     faClone,
@@ -54,76 +35,95 @@ import {
     faCommentAlt,
     faCompressArrowsAlt,
     faCut,
+    faEdit,
     faEllipsisV,
     faEraser,
     faExclamation,
+    faExpand,
+    faExternalLinkAlt,
+    faExternalLinkSquareAlt,
+    faEye,
     faFileAlt,
     faFileAudio,
+    faFileDownload,
     faFilePdf,
     faFilm,
     faFilter,
+    faFolderOpen,
     faFont,
     faGlobeAsia,
+    faHandPointLeft,
     faHighlighter,
+    faHome,
+    faImage,
+    faLocationArrow,
+    faLongArrowAltLeft,
     faLongArrowAltRight,
     faMicrophone,
+    faMinus,
+    faMobile,
     faMousePointer,
     faMusic,
     faObjectGroup,
+    faPaintBrush,
+    faPalette,
     faPause,
     faPen,
     faPenNib,
     faPhone,
     faPlay,
+    faPlus,
     faPortrait,
+    faQuestionCircle,
+    faQuoteLeft,
     faRedoAlt,
+    faReply,
+    faSearch,
     faStamp,
     faStickyNote,
+    faStop,
+    faTasks,
+    faTerminal,
+    faTh,
+    faThLarge,
     faThumbtack,
+    faTimes,
+    faToggleOn,
+    faTrash,
+    faTrashAlt,
     faTree,
     faTv,
-    faBook,
     faUndoAlt,
     faVideo,
-    faAsterisk,
-    faBrain,
-    faImage,
-    faPaintBrush,
-    faTimes,
-    faEye,
-    faHome,
-    faLongArrowAltLeft,
-    faBars,
-    faTh,
-    faChevronLeft,
-    faAlignRight,
-    faAlignLeft,
+    faWindowClose,
+    faWindowMaximize,
+    faFile as fileSolid,
 } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, observable, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
-import { Docs, DocumentOptions, DocUtils } from '../client/documents/Documents';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnTrue } from '../Utils';
 import { CollectionViewType, DocumentType } from '../client/documents/DocumentTypes';
+import { Docs, DocumentOptions } from '../client/documents/Documents';
 import { CurrentUserUtils } from '../client/util/CurrentUserUtils';
 import { ScriptingGlobals } from '../client/util/ScriptingGlobals';
-import { SettingsManager, ColorScheme } from '../client/util/SettingsManager';
+import { SettingsManager } from '../client/util/SettingsManager';
 import { Transform } from '../client/util/Transform';
 import { UndoManager } from '../client/util/UndoManager';
-import { TabDocView } from '../client/views/collections/TabDocView';
 import { GestureOverlay } from '../client/views/GestureOverlay';
+import { TabDocView } from '../client/views/collections/TabDocView';
 import { AudioBox } from '../client/views/nodes/AudioBox';
 import { DocumentView } from '../client/views/nodes/DocumentView';
-import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu';
 import { RadialMenu } from '../client/views/nodes/RadialMenu';
+import { RichTextMenu } from '../client/views/nodes/formattedText/RichTextMenu';
 import { Doc, DocListCast } from '../fields/Doc';
 import { InkTool } from '../fields/InkField';
 import { List } from '../fields/List';
 import { ScriptField } from '../fields/ScriptField';
 import { Cast, FieldValue, StrCast } from '../fields/Types';
-import { emptyFunction, emptyPath, returnEmptyDoclist, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero } from '../Utils';
-import { Uploader } from './ImageUpload';
 import './AudioUpload.scss';
+import { Uploader } from './ImageUpload';
 import './ImageUpload.scss';
 import './MobileInterface.scss';
 
diff --git a/src/typings/index.d.ts b/src/typings/index.d.ts
index 8f21966ae..d46977816 100644
--- a/src/typings/index.d.ts
+++ b/src/typings/index.d.ts
@@ -14,9 +14,7 @@ declare module 'pdfjs-dist/web/pdf_viewer';
 declare module 'react-jsx-parser';
 
 declare module 'express-flash';
-declare module 'connect-flash' {
-    interface flash {}
-}
+declare module 'connect-flash';
 declare module 'connect-mongo';
 declare module '@mui/material';
 
diff --git a/test/test.ts b/test/test.ts
index 489aa3025..ee14a9340 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -1,37 +1,41 @@
 import { expect } from 'chai';
 import 'mocha';
 const { JSDOM } = require('jsdom');
-const dom = new JSDOM("", {
-    url: `http://localhost:${resolvedPorts.server}`
+const dom = new JSDOM('', {
+    url: `http://localhost:${resolvedPorts.server}`,
 });
 (global as any).window = dom.window;
 
-
-import { autorun, reaction } from "mobx";
+import { reaction } from 'mobx';
+import { resolvedPorts } from '../src/client/util/CurrentUserUtils';
 import { Doc } from '../src/fields/Doc';
+import { createSchema, defaultSpec, makeInterface } from '../src/fields/Schema';
 import { Cast } from '../src/fields/Types';
-import { createSchema, makeInterface, defaultSpec } from '../src/fields/Schema';
 import { ImageField } from '../src/fields/URLField';
-import { resolvedPorts } from '../src/client/util/CurrentUserUtils';
-describe("Document", () => {
+describe('Document', () => {
     it('should hold fields', () => {
-        const key = "Test";
-        const key2 = "Test2";
+        const key = 'Test';
+        const key2 = 'Test2';
         const field = 15;
         const doc = new Doc();
         doc[key] = field;
-        const getField = Cast(doc[key], "number");
-        const getField2 = Cast(doc[key2], "number");
+        const getField = Cast(doc[key], 'number');
+        const getField2 = Cast(doc[key2], 'number');
         expect(getField).to.equal(field);
         expect(getField2).to.equal(undefined);
     });
 
     it('should update', () => {
         const doc = new Doc();
-        const key = "Test";
-        const key2 = "Test2";
+        const key = 'Test';
+        const key2 = 'Test2';
         let ran = false;
-        reaction(() => doc[key], (field) => { ran = true; });
+        reaction(
+            () => doc[key],
+            field => {
+                ran = true;
+            }
+        );
         expect(ran).to.equal(false);
 
         doc[key2] = 4;
@@ -44,55 +48,55 @@ describe("Document", () => {
 });
 
 const testSchema1 = createSchema({
-    a: "number",
-    b: "string",
-    c: "boolean",
+    a: 'number',
+    b: 'string',
+    c: 'boolean',
     d: ImageField,
-    e: Doc
+    e: Doc,
 });
 
 type TestDoc = makeInterface<[typeof testSchema1]>;
 const TestDoc = makeInterface(testSchema1);
 
 const testSchema2 = createSchema({
-    a: defaultSpec("boolean", true),
-    b: defaultSpec("number", 5),
-    c: defaultSpec("string", "hello world")
+    a: defaultSpec('boolean', true),
+    b: defaultSpec('number', 5),
+    c: defaultSpec('string', 'hello world'),
 });
 
 type TestDoc2 = makeInterface<[typeof testSchema2]>;
 const TestDoc2 = makeInterface(testSchema2);
 
 const testSchema3 = createSchema({
-    a: TestDoc2
+    a: TestDoc2,
 });
 
 type TestDoc3 = makeInterface<[typeof testSchema3]>;
 const TestDoc3 = makeInterface(testSchema3);
 
-describe("Schema", () => {
-    it("should do the right thing 1", () => {
-        const test1 = new Doc;
-        const test2 = new Doc;
-        const ifield = new ImageField(new URL("http://google.com"));
+describe('Schema', () => {
+    it('should do the right thing 1', () => {
+        const test1 = new Doc();
+        const test2 = new Doc();
+        const ifield = new ImageField(new URL('http://google.com'));
         test1.a = 5;
-        test1.b = "hello";
+        test1.b = 'hello';
         test1.c = true;
         test1.d = ifield;
         test1.e = test2;
         const doc = TestDoc(test1);
         expect(doc.a).to.equal(5);
-        expect(doc.b).to.equal("hello");
+        expect(doc.b).to.equal('hello');
         expect(doc.c).to.equal(true);
         expect(doc.d).to.equal(ifield);
         expect(doc.e).to.equal(test2);
     });
 
-    it("should do the right thing 2", () => {
-        const test1 = new Doc;
-        const test2 = new Doc;
-        const ifield = new ImageField(new URL("http://google.com"));
-        test1.a = "hello";
+    it('should do the right thing 2', () => {
+        const test1 = new Doc();
+        const test2 = new Doc();
+        const ifield = new ImageField(new URL('http://google.com'));
+        test1.a = 'hello';
         test1.b = 5;
         test1.c = test2;
         test1.d = true;
@@ -105,11 +109,11 @@ describe("Schema", () => {
         expect(doc.e).to.equal(undefined);
     });
 
-    it("should do the right thing 3", () => {
-        const test1 = new Doc;
-        const test2 = new Doc;
-        const ifield = new ImageField(new URL("http://google.com"));
-        test1.a = "hello";
+    it('should do the right thing 3', () => {
+        const test1 = new Doc();
+        const test2 = new Doc();
+        const ifield = new ImageField(new URL('http://google.com'));
+        test1.a = 'hello';
         test1.b = 5;
         test1.c = test2;
         test1.d = true;
@@ -122,40 +126,40 @@ describe("Schema", () => {
         expect(doc.e).to.equal(undefined);
     });
 
-    it("should do the right thing 4", () => {
+    it('should do the right thing 4', () => {
         const doc = TestDoc2();
         expect(doc.a).to.equal(true);
         expect(doc.b).to.equal(5);
-        expect(doc.c).to.equal("hello world");
+        expect(doc.c).to.equal('hello world');
 
-        const d2 = new Doc;
+        const d2 = new Doc();
         d2.a = false;
         d2.b = 4;
-        d2.c = "goodbye";
+        d2.c = 'goodbye';
         const doc2 = TestDoc2(d2);
         expect(doc2.a).to.equal(false);
         expect(doc2.b).to.equal(4);
-        expect(doc2.c).to.equal("goodbye");
+        expect(doc2.c).to.equal('goodbye');
 
-        const d3 = new Doc;
-        d3.a = "hello";
+        const d3 = new Doc();
+        d3.a = 'hello';
         d3.b = false;
         d3.c = 5;
         const doc3 = TestDoc2(d3);
         expect(doc3.a).to.equal(true);
         expect(doc3.b).to.equal(5);
-        expect(doc3.c).to.equal("hello world");
+        expect(doc3.c).to.equal('hello world');
     });
 
-    it("should do the right thing 5", async () => {
-        const test1 = new Doc;
-        const test2 = new Doc;
+    it('should do the right thing 5', async () => {
+        const test1 = new Doc();
+        const test2 = new Doc();
         const doc = TestDoc3(test1);
         expect(doc.a).to.equal(undefined);
         test1.a = test2;
         const doc2 = (await doc.a)!;
         expect(doc2.a).to.equal(true);
         expect(doc2.b).to.equal(5);
-        expect(doc2.c).to.equal("hello world");
+        expect(doc2.c).to.equal('hello world');
     });
 });
-- 
cgit v1.2.3-70-g09d2

